唯一一场每道题都有思路的比赛,感觉还行,虽然有思路不代表能AC,不过还是很开心的,因为除了E题的桶没想到外其他都是自力更生做出来的😊
![](https://cdn.jsdelivr.net/gh/uncleacc/Sucai/8~1.webp)

# A Sum of Round Numbers

# 分析

签到题,就是遍历数的每一位,求出非 0 的位数有几位,然后 int 一个 v=1,之后没走一个数 v*=10,然后当一位数不等于 0 时就乘上 v 就行了,这道题用字符串应该更简单,但是我想试试用 while,练练手

# CODE

#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

#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

#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

#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

#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 了😄

# CODE

#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 的序列两边添加数,先左后右轮换添加,例如:

  1. 8:2 4 1 3
  2. 8:5 2 4 1 3
  3. 8:5 2 4 1 3 6
  4. 8:7 5 2 4 1 3 6
  5. 8:7 5 2 4 1 3 6 8
    完成~,交了 AC 了。。AC 后看了测试数据发现我原来的代码测试数据 1 应该是对的啊!希望网友那位可以为我解惑(不胜感激)

# wrong CODE

#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

#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~ 撒花不要白嫖了,留下一个赞吧👍

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

PocketCat 微信支付

微信支付

PocketCat 支付宝

支付宝