Codeforces Round #555 (Div. 3)
A:模拟,出现重复的break。
1 #include <bits/stdc++.h> 2 #define lowbit(x) (x)&(-x) 3 #define il inline 4 #define lson l,mid-1,now 5 #define rson mid+1,r,now 6 #define max(a,b) a>b?a:b 7 #define min(a,b) a>b?b:a 8 #define per(i,a,b) for(int i=a;i<=b;i++) 9 #define rep(i,a,b) for(int i=a;i>=b;i--) 10 #define srand() srand(time(0)) 11 #define pi acos(-1.0) 12 #define printftime() printf("Time used = %.2f\n",(double)clock()/CLOCKS_PER_SEC) 13 using namespace std; 14 typedef long long ll; 15 int a[100]; 16 map<int,int>ma; 17 int main() 18 { 19 int cnt=0,ans=0; 20 scanf("%d",&cnt); 21 while(ma[cnt]==0){ 22 ma[cnt]=1; 23 //cout<<cnt<<endl; 24 ans++; 25 cnt++; 26 while(cnt%10==0)cnt/=10; 27 } 28 cout<<ans<<endl; 29 }
B:贪心,找到第一位转化后变大的位置,连续能换就换,不能换就break
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[200010]; 5 char s[200010]; 6 int main() { 7 int n; 8 scanf("%d",&n); 9 scanf("%s",s); 10 for(int i=0;i<n;i++) a[i+1]=s[i]-'0'; 11 map<int,int> mp; 12 for(int i=1;i<=9;i++) { 13 int x; 14 scanf("%d",&x); 15 mp[i]=x; 16 } 17 int st=-1; 18 for(int i=1;i<=n;i++) { 19 if(a[i]<mp[a[i]]) { 20 st=i; 21 break; 22 } 23 } 24 if(st!=-1) { 25 for(int i=st;i<=n;i++) { 26 if(a[i]<=mp[a[i]]) a[i]=mp[a[i]]; 27 else break; 28 } 29 } 30 for(int i=1;i<=n;i++) printf("%d",a[i]); 31 }
C:因为保证不相同,直接模拟,两边都能取,取小的。只有一边能取,就取哪边,没有能取的break
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[200010]; 5 6 int main() { 7 int n; 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 10 int maxx=-1; 11 int l=1,r=n; 12 string s; 13 while(l<=r) { 14 if(a[l]>maxx&&a[r]>maxx) { 15 if(a[l]<a[r]) { 16 s+='L'; 17 maxx=a[l]; 18 l++; 19 } else { 20 s+='R'; 21 maxx=a[r]; 22 r--; 23 } 24 } else if(a[l]>maxx) { 25 s+='L'; 26 maxx=a[l]; 27 l++; 28 } else if(a[r]>maxx) { 29 s+='R'; 30 maxx=a[r]; 31 r--; 32 } else break; 33 } 34 printf("%d\n",s.size()); 35 cout<<s<<endl; 36 }
D:构造,a、满足递增 b、总和为n c、a_i < a_i+1 <= a_i*2
首先,最小和k*(k+1)/2 > n 直接NO,然后就在1 2 3 ……k构造。 剩下的和为 now1=n-k*(k+1)/2。 可以把now1为k组 now2=now1/k,然后给a_i~a_k都加now2。剩下的和为 now3=now1-now2*k。 可以从后往前贪心。如果a_i+1<a_i*2,可以用now3填进去,最后判断now3是否为0。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 int a[100010]; 6 7 int main() { 8 ll n,k; 9 scanf("%lld%lld",&n,&k); 10 if(k*(k+1)/2>n) { 11 puts("NO"); 12 return 0; 13 } 14 n-=k*(k+1)/2; 15 int now1=n/k; 16 n-=now1*k; 17 n=n%k; 18 for(int i=1;i<=k;i++) a[i]=i+now1; 19 for(int i=k-1;i>=1;i--) { 20 if(n==0) break; 21 if(a[i]*2>a[i+1]) { 22 int cha=a[i]*2-a[i+1]; 23 if(n>cha) { 24 a[i+1]+=cha; 25 n-=cha; 26 } else { 27 a[i+1]+=n; 28 n=0; 29 } 30 } 31 } 32 if(n) puts("NO"); 33 else { 34 puts("YES"); 35 for(int i=1;i<=k;i++) printf("%d ",a[i]); 36 } 37 }
E:也算是贪心。因为字典序最小,肯定从前往后找。 在b数组里找 n-a[i] ,这样c_i就为0,找到 n-a[i]+1 ,那么c_i就为1,所以在b里找第一个大于等于(n-a_i )的数, 直接lower-bound(n-a_i) 。 如果找不到,那么b中最小的就是能使 c_i 最小的。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int a[200010]; 5 6 int main() { 7 int n; 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 10 multiset<int> b; 11 for(int i=1;i<=n;i++) { 12 int x; 13 scanf("%d",&x); 14 b.insert(x); 15 } 16 multiset<int>::iterator it; 17 for(int i=1;i<=n;i++) { 18 it=b.lower_bound(n-a[i]); 19 if(it==b.end()) it=b.begin(); 20 cout<<(a[i]+*it)%n<<' '; 21 b.erase(it); 22 } 23 }
埋骨何须桑梓地,人生无处不青山