AB 略
C
分情况讨论。首先最大值肯定不超过9。对于一位数,假如不是7,那么变成7的方式有以下几种:
一:通过这一位数每加一个9就减少1,不考虑进位(实际上就是第一位)可以直接算出。考虑进位那么下一位进的1就会和这一位减少的1抵消,除非出现下一位为0的情况,这是这一位可减少1,下一位每隔九次轮一回为0,于是只有当这一位为8答案才有可能小于9
二:通过下一位数的进位使得这一位数增加1,增加到9。这里需要注意的就是我们需要把最高位设置为0,例如96,就写成096
因为n<=10000000000,我们按位模拟就行
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int T,n,a[101],ans,cnt,nn;
void init()
{cnt=0;ans=0x3f3f3f3f3f;
}
void solve()
{cin>>n;nn=n;init();while(nn){a[++cnt]=nn%10;if(a[cnt]==7) {cout<<0<<endl; return ;}nn/=10;}a[cnt+1]=0;if(a[1]>7) ans=a[1]-7;else ans=a[1]+3;if(cnt==1) {cout<<a[1]<<endl; return ;}int x=0,k=1;for(int i=2;i<=cnt;i++){x=x*10+9;k*=10;int o=n%k;if(a[i]==8){for(int j=1;j<=8;j++)if(o+x*j<k*j) {ans=min(ans,j);break;}}}k=1;int kk=0;for(int i=2;i<=cnt+1;i++){int p;if(a[i]<7) p=7-a[i];else p=10-a[i]+7;k*=10;kk=kk*10+9;int t=n%k;for(int j=1;j<=8;j++){t+=kk;if(t/k==p){ans=min(ans,j);break;}}}cout<<ans<<endl;
}
signed main()
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>T;while(T--) solve();
}
E
如果一个序列不包含0,那么符合。有两个0,不符合。我们仅考虑有一个0是否符合即可。假设序列中有一个0位置为k,那么当k<=i<n时,一定符合,仅考虑当1<=i<k的情况。比较一个不包含0的序列在它的不同位置放0,我们发现左端的0的情况一定不会比右端的0情况差。设左端0位置p,右段q。当i>=q和i<p时两序列等价,考虑p<=i<q,此时左端0的情况一定符合,而右端0的情况不一定符合,故我们只需考虑最左端的0即可。用map算MEX,每一步比较大小即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int T,n,a[N],ans,b[N],t,minn;
void init()
{ans=t=0;
}
void solve()
{cin>>n;init();for(int i=1;i<=n;i++){cin>>a[i];if(a[i]!=0) b[++ans]=a[i];else if(!t) b[++ans]=a[i],t=1;}if(ans==1) {cout<<ans<<endl; return ;}map<int,int> m;for(int i=2;i<=ans;i++)m[b[i]]++;int s=0;while(1){if(m[s]) s++;else break;}minn=b[1];if(minn<s) {cout<<ans-1<<endl; return ;}for(int i=2;i<ans;i++){minn=min(minn,b[i]);m[b[i]]--;if(m[b[i]]==0&&s>b[i]){s=b[i];}if(minn<s) {cout<<ans-1<<endl; return ;}}cout<<ans<<endl;
}
signed main()
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>T;while(T--) solve();
}