唯一一场每道题都有思路的比赛,感觉还行,虽然有思路不代表能AC,不过还是很开心的,因为除了E题的桶没想到外其他都是自力更生做出来的😊   
A Sum of Round Numbers
分析
签到题,就是遍历数的每一位,求出非0的位数有几位,然后int一个v=1,之后没走一个数v*=10,然后当一位数不等于0时就乘上v就行了,这道题用字符串应该更简单,但是我想试试用while,练练手
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4+100; int main() { 	ios; 	int t,k; 	cin>>t; 	while(t--){ 		cin>>k; 		int cnt=0,x=k,v=1; 		while(k/10){ 			int tt=k%10; 			if(tt!=0) cnt++; 			k/=10; 		} 		cout<<cnt+1<<endl; 		while(x/10){ 			int tt=x%10; 			if(x/10&&tt!=0) cout<<tt*v<<" "; 			x/=10; v*=10; 		} 		cout<<(x%10)*v<<endl; 	} 	return 0; }
   | 
 
B - Same Parity Summands
分析
这道题是给你一个a和b,让你用b个同为偶数或者奇数的数加起来等于a,输出这些数,刚开始我一直在找规律,感觉很麻烦,找了半小时也没涵盖所有情况,后来发现直接暴力枚举就行了,我们可以考虑极端,当都为奇数时,让除了最后一个数以外的数都是1,然后最后一个数=a-(b-1),加起来正好等于a,同理都为偶数时,让除了最后一个数以外的数全部变成2,最后一个数为n-2*(k-1),条件都不符合输出NO想通这个就AC了
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4+100; int main() { 	ios; 	int t,k,n; 	cin>>t; 	while(t--){ 		cin>>n>>k; 		int m=n-(k-1); 		if(m>0&&m%2){ 			cout<<"YES"<<endl; 			for(int i=0;i<k-1;i++){ 				cout<<1<<" "; 			} 			cout<<m<<endl; 			continue; 		} 		m=n-2*(k-1); 		if(m>0&&m%2==0){ 			cout<<"YES"<<endl; 			for(int i=0;i<k-1;i++){ 				cout<<2<<" "; 			} 			cout<<m<<endl; 			continue; 		} 		cout<<"NO"<<endl; 		 		 	} 	return 0; }
   | 
 
C - K-th Not Divisible by n
分析
看题目就知道大意,不被n整除的第K个数,首先我们清楚被N整除的数之间的数数量一定是相同的,比如能整除8的:8 16 24…数之间都相差8,那这就是一个找规律嘛,用“%”找到该数在一段区间的那个位置,然后用“/”找到在第几个区间就行了
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4+100; int main() { 	ios; 	int t,k,n; 	cin>>t; 	while(t--){ 		int a,b; 		cin>>a>>b; 		int k=b%(a-1); 		if(k==0){ 			cout<<(b/(a-1)*a)-1<<endl; 		} 		else cout<<(b/(a-1)*a)+k<<endl; 	} 	return 0; }
   | 
 
D. Alice, Bob and Candies
分析
这道题好长啊,我第一眼就被吓住了,不战而屈人之兵,不过狠下心来读一读,发现就是一个双向指针往中间合拢,好像这叫双向队列~~,再多定义几个变量记录每次每个人吃多少,每个人上次吃了多少,就是一个模拟,只要能写对条件,就能AC了
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4; int val[MAXN]; int main() { 	ios; 	int t; cin>>t; 	while(t--){ 		int n,pa=0,pb=0,flg=0;; cin>>n; 		int sum=0; 		for(int i=1;i<=n;i++){ 			cin>>val[i]; 			sum+=val[i]; 		} 		int ea=0,eb=0,cnt=1,sa,sb,head=1,tail=n; 		while(tail-head>=0){ 			sa=0; sb=0; 			if(flg==0&&sum-ea-eb>pb){ 				while(sa<=pb){ 					sa+=val[head]; 					ea+=val[head]; 					head++;  				} 				pa=sa; flg=1; cnt++; 				continue; 			} 			if(flg==1&&sum-ea-eb>pa){ 				while(sb<=pa){ 					sb+=val[tail]; 					eb+=val[tail]; 					tail--; 				} 				pb=sb; flg=0; cnt++; 				continue; 			} 			cnt++; 			if(flg==0){ 				ea+=sum-ea-eb; 				break; 			}else{ 				eb+=sum-ea-eb; 				break; 			} 		} 		cout<<cnt-1<<" "<<ea<<" "<<eb<<" "<<endl; 	}  	return 0; } 双向队列超级简单,水题 #include<bits/stdc++.h> using namespace std; typedef long long ll; deque<int> dq; int main() {	 	int t; 	cin>>t; 	while(t--){ 		dq.clear(); 		int n; cin>>n; 		for(int i=1;i<=n;i++){ 			int temp; cin>>temp; 			dq.push_back(temp); 		} 		ll pa=0,pb=0,suma=0,sumb=0,res=1,ansa=0,ansb=0,cnt=0; 		while(!dq.empty()){ 			cnt++; 			suma=sumb=0; 			if(res&1){ 				while(suma<=pb&&!dq.empty()){ 					suma+=dq.front(); 					dq.pop_front(); 				} 				ansa+=suma;  				pa=suma; 			}else{ 				while(sumb<=pa&&!dq.empty()){ 					sumb+=dq.back(); 					dq.pop_back(); 				} 				ansb+=sumb; 				pb=sumb; 			} 			res++; 		} 		cout<<cnt<<" "<<ansa<<" "<<ansb<<endl; 	} 	return 0; }
   | 
 
E. Special Elements
分析
最好理解的一道题目🌝也是我唯一一道看了题解的题目😂一个前缀和,这道题数据量很小,只有8000,直接装进桶里就行了,而我就是没想到,一直在纠结怎么降低复杂度(好菜啊)求出每一个区间的和看看这个和对应的桶编号里面装没装数,其实是道水题
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4; int val[MAXN],book[MAXN]; int main() { 	ios; 	int t; cin>>t; 	while(t--){ 		memset(book,0,sizeof book); 		memset(val,0,sizeof val); 		int n; cin>>n; 		for(int i=1;i<=n;i++){ 			cin>>val[i]; 			book[val[i]]++; 			val[i]+=val[i-1]; 		} 		int cnt=0; 		for(int i=0;i<n-1;i++){ 			for(int j=i+2;j<=n;j++){ 				int sum=val[j]-val[i]; //				cout<<sum<<' '<<book[sum]<<endl; 				if(sum<=n&&book[sum]){ 					cnt+=book[sum]; 					 					book[sum]=0; 				} 			} 		} 		cout<<cnt<<endl; 	}  	return 0; }
   | 
 
F - Binary String Reconstruction
分析
又是思维题,给你一个n0,n1,n2让你构造一个二进制序列,这个序列子序列中00的个数为n0,01或10的个数为n1,11的个数为n2,首先n0和n2的序列容易构造,因为只包含一个数字,n1我们可以定义顺序为1010…n1=1:10 n1=2:101 n1=3:1010,每次增加一个数,单独构造容易,合起来难,三个序列合起来中间肯定会多出一些,所以只要在本上演算一下,再把多出的那一部分去掉就行了,然后我构造的序列顺序是n0n2n1,感觉这样构造简单🐶说实话我交代码时都没敢想能AC,因为感觉没考虑全,但是测试几组数据发现能过就抱着试一试的态度交上去了,结果A了:smile:
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4; int val[MAXN],book[MAXN]; int main() { 	ios; 	int t; cin>>t; 	while(t--){ 		int n0,n1,n2; 		string ans; 		cin>>n0>>n1>>n2; 		for(int i=1;i<=n0+1;i++){ 			if(n1!=0||n1==0&&n2==0) ans+="0"; 		} 		for(int i=1;i<=n2;i++){ 			ans+="1"; 		} 		for(int i=1;i<=n1;i++){ 			if(i%2) ans+="1"; 			else ans+="0"; 		} 		if(n0==0&&n1==0) ans+="1"; 		cout<<ans<<endl; 	}  	return 0; }
   | 
 
G - Special Permutation
分析
说实话我不知道这道题为啥放在最后,感觉难度并不大,反而挺简单的🌚就是让你构造一个相邻两个数之差的绝对值在2到4的区间内(闭区间),我们只要把奇偶分开就行了,但是我有一个疑问,我的思路是把偶数写在前面奇数的倒序列放在后面,例如:
8:2 4 6 8 7 5 3 1
很明显只有中间不符合条件,所以只动中间就行了,让7和5(奇数序列的前两个)交换:
8:2 4 6 8 5 7 3 1(满足条件)
再举个例子:
9:2 4 6 8 9 7 5 3 1
还是只动中间,因为9比8(奇数第一个和偶数最后一个)大所以让5跑到9中间(奇数第3个移动到奇数和偶数序列之间):
9:2 4 6 8 5 9 7 3 1(满足条件)
这样的思路我仔细想了想感觉没毛病,就交了,结果wrong了?我不服气,发现中间可能是换行的问题,又交又wrong…

我枯了,为啥?
后来换思路:
给2 4 1 3的序列两边添加数,先左后右轮换添加,例如:   
- 8:2 4 1 3  
 
- 8:5 2 4 1 3  
 
- 8:5 2 4 1 3 6  
 
- 8:7 5 2 4 1 3 6  
 
- 8:7 5 2 4 1 3 6 8
完成~,交了AC了。。AC后看了测试数据发现我原来的代码测试数据1应该是对的啊!希望网友那位可以为我解惑(不胜感激)

 

wrong CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
   | #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #define ios ios::sync_with_stdio(0) using namespace std; const int MAXN=1e4; void swap(int &a,int &b){ 	int t=a; 	a=b; 	b=t; } int val[MAXN],book[MAXN]; int main() { 	ios; 	int t; cin>>t; 	while(t--){ 		memset(val,0,sizeof val);  		int n; cin>>n; 		if(n==2||n==3){ 			cout<<-1<<endl; 			continue; 		} 		int tail=0; 		for(int i=2;i<=n;i+=2){ 			val[++tail]=i; 		} 		int flag=tail; 		int p=n%2?n:n-1; 		for(int i=p;i>=1;i-=2){ 			val[++tail]=i; 		} 		if(val[flag+1]<val[flag]) swap(val[flag+1],val[flag+2]); 		else{ 			for(int i=1;i<=n;i++){ 				if(i==flag+1){ 					printf("%d%c",val[flag+3],i==n?'\n':' '); 				} 				if(i==flag+3){ 					continue; 				} 				printf("%d%c",val[i],i==n?'\n':' '); 			} 			if(n==5) cout<<endl; 			continue; 		} 		for(int i=1;i<=n;i++) printf("%d%c",val[i],i==n?'\n':' '); 	}  	return 0; }
   | 
 
AC CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   | #include<stdio.h> #include<string> #include<string.h> #include<algorithm> #include<iostream> using namespace std; string ans; void bd(int n){ 	if(n<=9){ 		ans=(char)(n+'0')+ans; 	}else{ 		while(n!=0){ 			char c=(char)(n%10+'0'); 			ans=c+ans; 			n/=10; 		} 	} } void pd(int n){ 		if(n<=9){ 		ans+=(char)(n+'0'); 	}else{ 		char ch[2000]; 		int tail=0; 		while(n!=0){ 			char c=(char)(n%10+'0'); 			ch[++tail]=c; 			n/=10; 		} 		for(int i=tail;i>=1;i--){ 			ans+=ch[i]; 		} 	} } int main() { 	int t; cin>>t; 	while(t--){ 		ans.clear(); 		int n; cin>>n; 		if(n<=3){ 			puts("-1"); 			continue; 		} 		ans+="2 4 1 3"; 		int flag=1; 		for(int i=5;i<=n;i++){ 			if(i%2){ 				ans=" "+ans; 				bd(i); 			} 			else{ 				ans+=" "; 				pd(i); 			} 		} 		cout<<ans<<endl; }
   | 
 
Ending~撒花不要白嫖了,留下一个赞吧👍