首页 > 其他分享 >高一小学期2

高一小学期2

时间:2024-07-08 11:32:08浏览次数:11  
标签:dirs return di int 一小 long 学期 find

A.同类分布

本来看着挺像月之迷的(其实就是一模一样),但是鉴于我自己不是非常会打月之迷(其实应该自信点的,虽然当时是贺的题解但是大体思路还是会的),而且数据范围只有 \(2^{31}\),所以就去分块打表了.

赛时爆搜

#include<bits/stdc++.h>
using namespace std;
const int N=100000;
//int f[11][91][N+1];
#define int long long
int a,b;
int dfs(int pos,int digsum,int num,int r,bool limit){
//	if(r<=N and f[pos][digsum][num]) return f[pos][digsum][num];
//	cout<<pos<<" "<<digsum<<" "<<num<<" "<<r<<endl;
//	if(pos>r/10+1) return 0;
	int ans=0;
	for(int i=limit;i<=9;++i){
		if(num*10+i<=r){
			ans+=dfs(pos+1,digsum+i,num*10+i,r,false);
		}
		else break;
	}
	if(digsum and num%digsum==0) ans++;
	return ans;
//	if(r<=N) return ans;
//	return f[pos][digsum][num]=ans;
}
int sol(int r){
//	memset(f,0,sizeof f);
	return dfs(0,0,0,r,true);
}
signed main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
//	freopen("a.in","r",stdin);
//	freopen("out.out","w",stdout);
	cin>>a>>b;
	cout<<sol(b)-sol(a-1);
}

赛时分块打表

#include<bits/stdc++.h>
using namespace std;
#define int long long
int ans[]={
806095,1581855,2329984,3052160,3750525,4427492,5084970,5724686,6347468,6954793,
7732131,8481543,9205050,9904095,10581019,11237788,11875940,12497616,13103432,
13694682,14446019,15171368,15872614,16550673,17207734,17845948,18466778,19072027,19662166,
20238658,20966010,21669203,22349898,23008770,23647763,24268780,24873479,25463707,26039575,
26602369,27307487,27990025,28651439,29292198,29914298,30519347,31108837,31684643,32246926,
32796782,33480907,34144108,34787529,35411317,36017597,36607817,37183292,37745713,38295232,
38832914,39497335,40142121,40768651,41376852,41968476,42544806,43107279,43657184,44194636,
44720629,45366844,45994799,46605449,47198975,47777248,48340949,48891281,49429749,49956416,
50471934,51099607,51710497,52305518,52884417,53449198,54000471,54539065,55066115,55581915,
56087100,56697604,57292496,57872728,58438097,58990253,59529673,60057199,60573660,61079255,
61574510,62350092,63097869,63819541,64518767,65196025,65853422,66492929,67115939,67723180,
68315858,69065001,69788220,70486813,71164192,71820967,72459097,73080198,73686045,74277263,
74854848,75580173,76281192,76958934,77616432,78254516,78875101,79479726,80069949,80646304,
81209842,81913126,82593642,83252188,83891520,84512425,85116692,85705985,86281927,86844712,
87395222,88078277,88739789,89380423,90002919,90608076,91197276,91772241,92334568,92884400,
93422516,94086078,94729635,95353494,95959931,96550183,97125584,97687286,98236774,98774497,
99300966,99946350,100573004,101181179,101773075,102349517,102911768,103461177,103998784,
104524884,105040134,105668630,106279633,106873231,107451534,108015603,108566044,109104101,
109630965,110146773,110652019,111263448,111858755,112437880,113002507,113553847,114092524,
114619365,115135281,115640682,116135935,116731236,117311723,117877173,118429067,118968504,
119495888,120012050,120517675,121013081,121498549,122246148,122967486,123666231,124344352,
125002221,125641869,126264830,126872397,127465162,128044273,128767360,129465536,130142334,130799782
};
inline int locate(int x){
	return x/10000000;
}
inline bool check(int x){
	register int n=x;int d=0;
	while(n){
		d+=n%10;
		n/=10;
	}
	if(d and x%d==0) return true;
	return false;
}
signed main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	int l,r,anss=0;
	cin>>l>>r;
	if(locate(l)==locate(r) or locate(r)-locate(l)==1){
		for(int i=l;i<=r;++i){
			if(check(i)) anss++;
		}
	}
	else{
		anss=ans[locate(r)-1]-ans[locate(l)];
		for(int i=l;i<=(locate(l)+1)*10000000;++i){
			if(check(i)) anss++;
		}
		for(int i=locate(r)*10000000+1;i<=r;++i){
			if(check(i)) anss++;
		}
	}
	cout<<anss<<endl;
}

打表辅助程序

#include<bits/stdc++.h>
using namespace std;
bool check(int x){
	register int n=x;int d=0;
	while(n){
		d+=n%10;
		n/=10;
	}
	if(d and x%d==0) return true;
	return false;
}
#define int long long
int ans=0,cnt=0;
signed main(){
	for(int i=1;i<=2157483647;++i){
		if(check(i)) ans++;
		if(i%50000000==0){
			cout<<ans<<",";
			cnt++;
			if(cnt==10){
				cout<<endl;
			}
		}
	}
}

一跑觉得还挺快,心想这题包稳了.

结果赛后一测 RE 了,我寻思我表长只有 \(50\) 不太可能炸长度,结果点开一看,测试点是 \(10^{18}\) 的,气死了. 怎么题面还能锅.

也就是个板子题加强版,这里的话显然要根据数位和和原数来转移,判断的话直接取模看看就行,数位 \(sum'=sum+i\),原数 \(num'=10num+i\),这样就写完了一个爆搜.

然后这题要记的话,首先肯定不能直接把 \(num\) 这个 \(10^{18}\) 的范围拿过来开,所以显而易见要取下模再存. 但是取模的话毕竟不是原数,肯定会丢情况,赛时就卡在这了.

实际上题解给出的答案是:那你所有模数全跑一遍不就行了,(这不T?)因为是记搜,最坏复杂度 \(T(2\times 9\times 19\times sizeof_{f})=64980\),再加上 \(memset\) 耗时能过(实际上根本跑不满 \(sizeof_{f}\),不然就该T了).

#include<bits/stdc++.h>
using namespace std;
#define int long long
int f[20][200][200];
int len,a[20],mod;
int dfs(int pos,int sum,int num,int limit){
	if(pos>len){
		if(!sum) return 0;
		if(!num and sum==mod) return 1;
		return 0;
	}
	if(!limit and f[pos][sum][num]!=-1) return f[pos][sum][num];
	int ret=0;
	int res;
	if(limit){
		res=a[len-pos+1];
	}
	else res=9;
	for(int i=0;i<=res;++i){
		ret+=dfs(pos+1,sum+i,(10ll*num+i)%mod,i==res and limit);
	}
	if(limit) return ret;
	else return f[pos][sum][num]=ret;
}
int sol(int r){
	len=0;
	while(r) a[++len]=r%10,r/=10;
	int ans=0;
	for(mod=1;mod<=9*len;mod++){
		memset(f,-1,sizeof f);
		ans+=dfs(1,0,0,1);
	}
	return ans;
}
signed main(){
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	int l,r;
	cin>>l>>r;
	cout<<sol(r)-sol(l-1);
}

B.千山鸟飞绝

很显然这个题的难点有三个:一个是找坐标,一个是找极值,一个是插入删除

在赛事写了一个有序数列二分查找套手写堆,不用优先队列是因为没办法删除节点,可惜的是并没有调出来

赛时代码(肚子不舒服导致脑子也不太好使,写的比较抽象了,但是确实是有序数列二分查找套手写堆,只不过删除是 \(O(n)\) 的)

#include<bits/stdc++.h>
using namespace std;
const int N=30001;
class direction{
	public:
		map<pair<int,int>,int>d;
		int cnt=0;
		inline int find(int _x,int _y){
			if(!d.count({_x,_y})){
				d[{_x,_y}]=++cnt;
			}
			return d[{_x,_y}];
		}
};
direction di;
struct b{
	int id,ww;
	bool operator ==(const b &x)const{
		if(id==x.id) return true;
		return false;
	}
	bool operator !=(const b &x)const{
		if(id==x.id) return false;
		return true;
	}
	bool operator <(const b &x)const{
		return ww<x.ww;
	}
};
template<typename T>
class ordered_vector{
	public:
		vector<T>v;
		inline int find(T x){
			for(int i=0;i<=(int)v.size()-1;++i){
				if(v[i]==x) return i;
			}
			return v.size();
		}
		inline int lower_bound(T x){
			return (std::lower_bound(v.begin(),v.end(),x)-v.begin());
		}
		inline int size(){
			return v.size();
		}
		inline void insert(T x){
			int pos=lower_bound(x);
			if((pos<=(int)v.size()-1 and (T)v[pos]!=x) or (pos>=(int)v.size())){
				v.insert(v.begin()+lower_bound(x),x);
			}
		}
		inline int it(T x){
			int pos=lower_bound(x);
			return pos;
		}
		inline T maxn(){
			return v.back();
		}
		inline void remove(T id){
			for(int i=0;i<=(int)v.size()-1;++i){
				if(v[i]==id){
					v.erase(v.begin()+i);
					break;
				}
			}
		}
		T operator [](int x){
			return v[x];
		}
};
struct poi{
	ordered_vector<b> m;
	int val;
	bool operator<(const poi &x)const{
		return val<x.val;
	}
	bool operator ==(const poi &x)const{
		if(val==x.val) return true;
		return false;
	}
	bool operator !=(const poi &x)const{
		if(val==x.val) return false;
		return true;
	}
};
ordered_vector<poi> dirs;
int www[N],xx[N],yy[N],maxww[N],maxtj[N];
int main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	int n;
	cin>>n;
	for(int i=1;i<=n;++i){
		int x,y,ww;
		cin>>ww>>x>>y;
		www[i]=ww;
		xx[i]=x;yy[i]=y;
		dirs.insert({{},di.find(x,y)});
		dirs[dirs.it({{},di.find(x,y)})].m.insert({i,ww});
	}
	for(int v=1;v<=n;++v){
		maxtj[v]=max(maxtj[v],dirs[dirs.it({{},di.find(xx[v],yy[v])})].m.size());
		maxww[v]=max(maxww[v],dirs[dirs.it({{},di.find(xx[v],yy[v])})].m.maxn().ww);
	}
	int q;cin>>q;
	for(int i=1;i<=q;++i){
		int v,x,y;
		cin>>v>>x>>y;
		dirs[dirs.it({{},di.find(xx[v],yy[v])})].m.remove(b{v,www[v]});
		xx[v]=x;yy[v]=y;
		dirs.insert({{},di.find(x,y)});
		dirs[dirs.it({{},di.find(x,y)})].m.insert({v,www[v]});
		maxtj[v]=max(maxtj[v],(int)dirs[dirs.it({{},di.find(xx[v],yy[v])})].m.v.size());
		maxww[v]=max(maxww[v],dirs[dirs.it({{},di.find(xx[v],yy[v])})].m.maxn().ww);
	}
	for(int i=1;i<=n;++i){
		cout<<1ll*maxtj[i]*maxww[i]<<endl;
	}
}

然后赛后觉得这个代码还是太抽象了,我自己都懒得调,所以换了一种思路,写的有序数列二分查找套std::map,写起来感觉简单一点,但是这个复杂度肯定是过不了,\(50pts\),隔壁 9G 似乎拿暴力打出来了,看来还是我这个暴力复杂度不够优

平衡树 TBA

标签:dirs,return,di,int,一小,long,学期,find
From: https://www.cnblogs.com/HaneDaCafe/p/18289575

相关文章

  • 小学期第一周(7.1-7.7)
    7.1 周一为啥被人学校都放假了我们还有小学期【微笑]开玩笑其实我高兴得很,毕竟我是如此热爱学习今天小学期一人分了四道题我把每道题都看了看答案最后选了四道代码比较少的,这样验收的时候还简单点什么?问我为什么从网上找答案不自己写?那我也得会写才行啊,我的基础真的不敢恭......
  • 数据结构小学期第七天
    今天继续学习Springboot的项目实战今天了解了一下,如何在自己登陆后,还能让界面知道是谁在进行操作,这个功能的实现需要JWT令牌的作用我们需要先引入一个JWT依赖1<!--java-JWT坐标-->2<dependency>3<groupId>com.auth0</groupId>4<artifa......
  • 小学期第一次博客
    一、配置虚拟机环境首先,安装和配置虚拟机是整个项目的基础。选择适当的虚拟机管理软件(如VirtualBox或VMware)并安装Linux操作系统(如Ubuntu或CentOS)。配置好虚拟机后,需要确保虚拟机的网络设置为桥接模式,以便能够与外部网络通信。二、安装和配置Hadoop下载和安装Hadoop:从Hadoop的......
  • 数据结构小学期第六天
    今天完全实现了九宫格拼图游戏,具备一键通关功能按下W键,查看原图功能按住A键不松,移动图片按上下左右键,如果你自己想要实现这个功能,需要自己的图片,图片格式要求。每个小图片是105*105,完整图片是315*315.有人想要做一下,可以试一试。代码如下启动类1importcom.itheima.ui.GameJ......
  • 【2023-2024第二学期】助教工作学期总结——数字电路与逻辑设计助教
    一、助教工作的具体职责和任务协助教师引导大一转专业学生如何学习本门课程,收集学生问题、定期答疑、协助教师批改作业并跟踪作业完成情况,实验指导,改进课程建设。指导学生学习《数字电路与逻辑设计》。并指导学生完成《数字电路与逻辑设计实验》。二、助教工作的每周时长和具体......
  • 助教工作学期总结
    一、助教工作的具体职责和任务老师的配合:    协助老师完成作业的批改、作业的评分、登记成绩二、助教工作的每周时长和具体安排    没有固定的工作时间和具体安排,在布置的作业截至后对作业进行批改、评分;大作业答辩前安排好答辩名单,课程结课后按照老师要求完成成绩录......
  • 【2023-2024第二学期】助教工作学期总结(教务处助教)
    一、助教工作的具体职责和任务帮助老师整理试卷以及存放协助老师做会议记录表二、助教工作的每周时长和具体安排每周工作时间不定,一般情况下由老师通知,课余时间随叫随到,具体安排是做会议记录表和其他事情三、对助教工作反思第一,工作时要细心,不要贪图一时快,要细心照顾每一个......
  • 助教工作学期总结
    一、助教工作的具体职责和任务1.老师的配合:协助老师将2023年下学期试卷整理入库2.与课程其他助教的配合:共同完成了2023年下学期期末试卷的装订二、助教工作的每周时长和具体安排没有特定的工作时间及每周具体安排,一般是课余时间老师需要随叫随到三、因为......
  • 数据结构小学期第三天
    今天试着完成第二阶段的目标,实现九宫格拼图游戏,但是看着教程只有4*4的我也只能先按照这个做了APP.class1importcom.itheima.ui.GameJFrame;2importcom.itheima.ui.LoginJFrame;3importcom.itheima.ui.RegisterJFrame;45publicclassApp{6publicstat......
  • 复旦大学2023--2024学年第二学期高等代数II期末考试情况分析
    一、期末考试成绩班级前几名的同学施想(95)、侯煜天(94)、刘升(92)、洪临依(92)、王龙晨(92)、文俊(90)、徐亦闵(89)、邓海斌(89)、褚乐一(89)二、总评成绩计算方法作业成绩根据交作业的次数决定。本学期提交作业共13次,10次100分,少1次扣10分。总评成绩=作业成绩*15%+期中成绩*......