Codeforces Round #491 (Div. 2)
https://codeforces.com/contest/991
A
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<ll>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 1000006 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=998244353; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 24 int main(){ 25 std::ios::sync_with_stdio(false); 26 int a,b,c,n; 27 cin>>a>>b>>c>>n; 28 int ans=n-a-b+c; 29 if(ans>0&&a<n&&b<n&&c<n&&n-ans>=a&&n-ans>=b&&n-ans>=c&&c<=a&&c<=b&&ans<=n) cout<<ans<<endl; 30 else cout<<-1<<endl; 31 }
B
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<ll>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 1000006 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=998244353; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 int n; 24 int a[105]; 25 26 int main(){ 27 std::ios::sync_with_stdio(false); 28 cin>>n; 29 ll sum=0; 30 for(int i=1;i<=n;i++) { 31 cin>>a[i]; 32 sum+=a[i]; 33 } 34 sort(a+1,a+n+1); 35 if(round(sum*1.0/n)==5){ 36 cout<<0<<endl; 37 return 0; 38 } 39 for(int i=1;i<=n;i++){ 40 sum+=5-a[i]; 41 if(round(sum*1.0/n)==5){ 42 cout<<i<<endl; 43 break; 44 } 45 } 46 }
C
题意:a有n个糖果,在开始的时候 a 选择一个整数k,表示他每天会吃k个糖果,b也想吃糖果,他每天会吃当前数量的10%(下取整)的糖果,a先开始吃,问a选择的k值最小为多少,使得他吃的糖果的数量大于等于总数的一半。
思路:二分最小值即可。注意:取10%的时候要用tmp/10,不能用tmp*0.1,会有精度问题(被坑了好久)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<ll>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 1000006 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=998244353; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 ll n; 24 25 bool Check(ll mid){ 26 ll sum1=0,sum2=0; 27 ll tmp=n; 28 ll t; 29 while(tmp){ 30 if(tmp>=mid){ 31 tmp-=mid; 32 sum1+=mid; 33 } 34 else { 35 sum1+=tmp; 36 tmp=0; 37 } 38 if(tmp>=10){ 39 t=tmp/10; 40 sum2+=t; 41 tmp-=t; 42 } 43 } 44 if(sum1>=sum2) return true; 45 return false; 46 } 47 48 int main(){ 49 std::ios::sync_with_stdio(false); 50 cin>>n; 51 ll L=1,R=n,mid; 52 while(L<=R){ 53 mid=L+R>>1; 54 if(Check(mid)){ 55 R=mid-1; 56 } 57 else{ 58 L=mid+1; 59 } 60 } 61 cout<<L<<endl; 62 }
D
题意:给定宽为两行的矩阵,问能放多少木块。
思路:因为只有两行,所以直接贪心即可,把每列有空的地方能放则放,要注意,当第一列遍历到i位置时,第二列i-1位置是否为空
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<ll>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 1000006 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=998244353; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 int book[5][105]; 24 int len; 25 string s1,s2; 26 27 bool Check(int x){ 28 if(x-1>=0){ 29 if(!book[0][x]&&!book[1][x-1]&&!book[1][x]&&s1[x]=='0'&&s2[x-1]=='0'&&s2[x]=='0'){ 30 book[0][x]=1;book[1][x-1]=1;book[1][x]=1; 31 return true; 32 } 33 } 34 if(x+1<len){ 35 if(!book[0][x]&&!book[1][x+1]&&!book[1][x]&&s1[x]=='0'&&s2[x+1]=='0'&&s2[x]=='0'){ 36 book[0][x]=1;book[1][x+1]=1;book[1][x]=1; 37 return true; 38 } 39 if(!book[0][x]&&!book[0][x+1]&&!book[1][x+1]&&s1[x]=='0'&&s1[x+1]=='0'&&s2[x+1]=='0'){ 40 book[0][x]=1;book[0][x+1]=1;book[1][x+1]=1; 41 return true; 42 } 43 if(!book[0][x]&&!book[0][x+1]&&!book[1][x]&&s1[x]=='0'&&s1[x+1]=='0'&&s2[x]=='0'){ 44 book[0][x]=1;book[0][x+1]=1;book[1][x]=1; 45 return true; 46 } 47 } 48 49 return false; 50 } 51 52 int main(){ 53 std::ios::sync_with_stdio(false); 54 cin>>s1>>s2; 55 len=s1.length(); 56 int ans=0; 57 for(int i=0;i<len;i++){ 58 if(!book[0][i]){ 59 if(Check(i)){ 60 ans++; 61 } 62 } 63 } 64 cout<<ans<<endl; 65 }
E
题意:给你一个数字序列A(长度不超过18位),问有多少个序列B满足:
1、A中所有数字都一定要在B中出现过;
2、B中所有数字也一定要在A中出现过;
3、序列B不能以0开头
比如:如果看到数字2028,它可能实际的车号可能是2028,8022,2820或者是820。 而80号、22208号、52号肯定不是这辆车的号码。 而且,实际的车号不能以数字0开头,例如,数字082不能也是实际的车号。 给定看到的数字n,求出所有可能的车号种数。
思路:枚举各个位上出现的数的个数。先不考虑前导0的情况下,车号总数为:车号位数之和的阶乘除以各个位数的个数。然后在减去前导0的情况即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<ll>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 1000006 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=998244353; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 int num[15]; 24 ll fac[20]; 25 ll sum[15]; 26 ll ans; 27 28 void dfs(int pos){ 29 if(pos==10){ 30 ll co=0; 31 for(int i=0;i<10;i++){ 32 co+=sum[i]; 33 } 34 ll tmp=fac[co]; 35 for(int i=0;i<10;i++) tmp/=fac[sum[i]]; 36 if(sum[0]>=1) tmp-=(tmp*sum[0]/co); 37 ans+=tmp; 38 return; 39 } 40 for(int i=1;i<=num[pos];i++){ 41 sum[pos]=i; 42 dfs(pos+1); 43 } 44 if(num[pos]==0) dfs(pos+1); 45 } 46 47 int main(){ 48 std::ios::sync_with_stdio(false); 49 string str; 50 fac[0]=1; 51 for(int i=1;i<20;i++) fac[i]=fac[i-1]*i; 52 cin>>str; 53 for(int i=0;i<str.length();i++){ 54 num[str[i]-'0']++; 55 } 56 dfs(0); 57 cout<<ans<<endl; 58 }
F
题意:给定n,把n简短化,比如:2000000000变成2*10^9,注意,不能使用括号,不能有2^3^4这样的形式
思路:先预处理出满足条件的a^b的形式,然后枚举这样的式子,在需要的情况下添加‘*’和‘+’,贪心判断长度即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<ll>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 1000006 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=998244353; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 map<ll,string>mp; 24 int main(){ 25 std::ios::sync_with_stdio(false); 26 ll n; 27 cin>>n; 28 ll nn=sqrt(n); 29 string tmp; 30 for(ll i=2;i<=nn;i++){ 31 ll num=i*i; 32 int co=2; 33 while(num<=n){ 34 tmp=to_string(i)+"^"+to_string(co); 35 if(!mp.count(num)) mp[num]=to_string(num); 36 if(mp[num].size()>tmp.size()) mp[num]=tmp; 37 co++; 38 num*=i; 39 } 40 } 41 string ans=to_string(n); 42 map<ll,string>::iterator it; 43 for(it=mp.begin();it!=mp.end();it++){ 44 tmp=""; 45 ll a=n/it->first,b=n%it->first; 46 if(a>1){ 47 if(mp.count(a)) tmp=mp[a]; 48 else tmp=to_string(a); 49 tmp+="*"; 50 } 51 tmp+=it->second; 52 if(b) tmp=tmp+"+"+(mp.count(b)?mp[b]:to_string(b)); 53 if(ans.size()>tmp.size()) ans=tmp; 54 } 55 56 cout<<ans<<endl; 57 }