Codeforces Round #629 (Div. 3)(A-D)

A 取模運算就行。

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int main()
{
	ll t,n,m;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		cout<<(m-n%m)%m<<endl;//n%m=0時需要輸出0,再取模一次就可以了
	}
	return 0;
}

B 求第k個全排列,數據範圍太大直接全排列會超時的,這個字符串有些特殊,是可以找規律了,已知兩個b的位置分別是n-1,n-2,每次全排列是先移動第一個b,然後移動第二個b,當兩個相鄰後,第一個b想右移動,第二個b回位置n,然後再繼續移動第二個b,知道兩個b相鄰再重複前面的。
所以可以找到,第一個b移動0次的最小k是1,第一個b移動1次的最小k是2,移動三次的最小k是4…有了這個規律就可以確定第一個b移動幾次就可以確定它的位置,然後第二個b最多不會超多第一個的次數所以減一下就是了,這樣兩個b的位置定了剩下就全是b了,還需要特判一下如果第一個b溢出了就輸出字典序最大的串(bbaa…)就行了

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll  a[200010];
void init()//預處理,我算的是最小步數減1,所以後邊查找m-1
{
	a[1]=1;
	for(int i=1;i<=100000;i++)
		a[i]=a[i-1]+i;
	return ;
}
int main()
{
	init();
	ll t,n,m;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		int l=upper_bound(a,a+100000,m-1)-a,r;//
		l--;//找到的是第一個大於m-1的位置,所以減1纔是第一個b的位置
		r=m-1-a[l];//l,r是左移的位數
		if(l>=n-1) //特判b溢出
		{
			cout<<"bb";
			for(int i=1;i<=n-2;i++) cout<<'a';
		}
		else 
		{
			for(int i=1;i<=n;i++)
				if(i+l==n-1||i+r==n) cout<<'b';
				else cout<<'a';
		}
			cout<<endl;
	}
	return 0;
}

C 找到滿足它的規則並且最大值儘量小的值,就是儘量平分那個值。
0,2都是可以平分的,只有1不是,假設我們分爲兩個值a,b。從高位向低位遍歷,0和2是可以平分的不用管,直到第一個的1的位置,只能分爲0和1假設a的只以爲分爲1,b的這一位分爲0,那麼不管不管後面再怎麼分a一定大於b,那麼後面就要在和爲s(已知的那個數)的情況下使a儘量小,那麼只有一種分法了,a後面全爲0,b後面和s相等,所以答案就出來了
找到第一個1的位置就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010;
char a[N],b[N],s[N];
int t,n; 
 
int main(){
	cin>>t;
	while(t--){
		cin>>n>>s;
		int len = strlen(s);
		int l=len;
		for(int i=0;i<len;i++)
			if(s[i]=='1')
			{
				l=i;
				break;
			}
		for(int i=0;i<l;i++) cout<<(s[i]=='2'?1:0);
		if(l<len) 
		{
			cout<<1;
			for(int i=l+1;i<len;i++) cout<<0;
		}
		cout<<endl;
		for(int i=0;i<len;i++)
			if(i<l) cout<<(s[i]=='2'?1:0);
			else if(i==l) cout<<0; 
			else cout<<s[i];
		cout<<endl;
	}
	return 0;
}

D 已知n個動物都有一個種類,他們排成一個圈做遊戲,讓你爲他們染色,只有一個條件相鄰的兩個不同種類的動物不能同色(這個還有一個隱含條件:相鄰的兩個同類型的動物可以同色也可以不同色)。
如果他們不是一個圈的話用兩種顏色是一定可以染成功的,第一個染1然後依次向後遍歷,如果當前與前一個類型相同染一樣的顏色,否則染和前一個不同的顏色,這樣一定是可行的,但是現在他們圍成了一個圈,會多出來一個條件n和1是相鄰的,那麼我們按上面染色後n和1可能會發生衝突(前n個的顏色一定是可行的),他倆不同類型但是染了同種顏色這樣是不合理的,那麼我們可以怎樣去修改呢,請看前面黑體部分,如果有相鄰且同類型的時我們染成了同顏色,其實是可以染成不同顏色的,所以我們按照這樣的思路再去染一遍,如果能使得n和1不同顏色那麼兩種顏色就是可行的,如果不能呢再加一種顏色一定是可行的,這裏我沒有仔細去證改變一次顏色後n的顏色沒變就一定不會變了就直接染3了,湊合看吧,反正a了hhh。

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int N = 400010;
int  a[N],b[N],s[N];
int t,n; 
int c[N];
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		bool flag=1;
		for(int i=1;i<=n;i++)
		 	cin>>a[i];
		int x=1,l=-1;//x顏色的種類,l記錄類型相同且相鄰的位置
		c[0]=1;//顏色
		a[0]=a[1];//確保第一個染成1
		for(int i=1;i<=n;i++) 
		{
			if(a[i]!=a[i-1]) 
			{	
				c[i]=3-c[i-1];//顏色反轉
				x=2;
			}
			else c[i]=c[i-1],l=i;
		}
		if(a[n]!=a[1]&&c[n]==c[1])
		{
			if(l!=-1)//如果衝突從l向後再染一遍
			{
				c[l]=3-c[l-1];
				for(int i=l+1;i<=n;i++)
					if(a[i]!=a[i-1]) c[i]=3-c[i-1];
					else c[i]=c[i-1];
			}
			if(a[n]!=a[1]&&c[n]==c[1]) x=c[n]=3;
		}
		cout<<x<<endl;
		for(int i=1;i<=n;i++) cout<<c[i]<<' ';
		cout<<endl;	
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章