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;
}