A
题意:
一串01字符串,求最少删掉几个0,使得1连续
思路:
找1的l,r,数出区间0的个数

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define il inline
5 #define it register int
6 #define inf 0x3f3f3f3f
7 #define lowbit(x) (x)&(-x)
8 #define mem(a,b) memset(a,b,sizeof(a))
9 #define mod 998244353
10 const int maxn=1e6+10;
11 int n,k;
12 char s[200];
13 int main(){
14 scanf("%d",&n);
15 while(n--){
16 scanf("%s",s);
17 int l1=strlen(s),sum=0,l=-1,r=-1;
18 for(it i=0;i<l1;i++){
19 if(s[i]=='1' && l==-1){
20 l=i;
21 }
22 else if(s[i]=='1'){
23 r=i;
24 }
25 }
26 for(it i=l;i<=r;i++){
27 if(s[i]=='0'){sum++;}
28 }
29 printf("%d\n",sum);
30 }
31 return 0;
32 }
B
题意:
输入n,g,b
需要施工n天,g天好天,b天坏天,这样连续,这n天里,一半的时间(奇数5一半要算3)要好天工作,最少需要几天
思路:
一半时间/g,剩余时间/b,如果前者比后者大,需要(前者-1)*b+一半时间
其他都是n

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define il inline
5 #define it register int
6 #define inf 0x3f3f3f3f
7 #define lowbit(x) (x)&(-x)
8 #define mem(a,b) memset(a,b,sizeof(a))
9 #define mod 998244353
10 const int maxn=1e6+10;
11 int t;
12 ll n,b,g;
13 int main(){
14 scanf("%d",&t);
15 while(t--){
16 scanf("%lld%lld%lld",&n,&g,&b);
17 ll zong=0;
18 ll nn=(n+1)/2,sheng=n-nn;
19 ll yi=(nn-1)/g+1,er=(sheng-1)/b+1;
20 //cout<<yi<<er<<endl;
21 if(yi>er){
22 zong=nn-(yi-1)*g+(yi-1)*(g+b);
23 printf("%lld\n",zong);
24 }
25 else{
26 zong=n;
27 printf("%lld\n",zong);
28 }
29 }
30 return 0;
31 }
C
题意:
给一个小写字符串s
需要重新排序a~z,使得重新排完的a~z可以符合s中每个字符相邻的字符与重新排完序的a~z中的字符相邻的字符是一样的
如果有输出其中一个,如果没有输出NO
思路:
模拟,判断一下是否矛盾

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define il inline
5 #define it register int
6 #define inf 0x3f3f3f3f
7 #define lowbit(x) (x)&(-x)
8 #define mem(a,b) memset(a,b,sizeof(a))
9 #define mod 998244353
10 const int maxn=1e6+10;
11 int t,vis[27];
12 char s[21000];
13 int main(){
14 scanf("%d",&t);
15 while(t--){
16 scanf("%s",s);
17 string ans;
18 int l=strlen(s);mem(vis,0);
19 ans+=s[0];vis[s[0]-'a']=1;it f=1;
20 for(it i=1;i<l;i++){
21 it c=s[i]-'a';
22 if(!vis[c]){vis[c]=1;
23 it l1=ans.size();it ff=1;
24 for(it j=0;j<l1;j++){
25 if(s[i-1]==ans[j]){
26 if(j==0){
27 ans=s[i]+ans;ff=0;break;
28 }
29 else if(j==l1-1){
30 ans+=s[i];ff=0;break;
31 }
32
33 }
34 }
35 if(ff){f=0;break;}
36 }
37 else{
38 it l1=ans.size();it ff=0;
39 for(it j=0;j<l1;j++){
40 if(s[i]==ans[j]){
41 if(j>0 && s[i-1]==ans[j-1]){ff=1;}
42 if(j<l1-1 && s[i-1]==ans[j+1]){ff=1;}
43 }
44 }
45 if(!ff){f=0;break;}
46 }
47 }
48 if(!f){printf("NO\n");continue;}
49 for(it i=0;i<26;i++){
50 if(!vis[i]){
51 ans+=('a'+i);
52 }
53 }
54 printf("YES\n");
55 cout<<ans<<endl;
56 }
57 return 0;
58 }
D
题意:
给n,m,输入m个数字
这m个数字都是2的幂次范围。
现在要将n给填满,m个数字可以对半切,步数+1
求最少步数可以将n刚好填满
思路:
m个数字用二进制数组vis保存,n也用另一个二进制数组ans保存
从1~64循环
如果ans[i]==1,vis[i]==1,vis[i]--;vis[i+1]+=vis[i]/2;
但如果ans[i]==1,vis[i]==0,就要找i之后最近的一个vis[j]==1,vis[j]--,vis[i]+=(1<<(j-i)),步数+=j-i,vis[i]--;vis[i+1]+=vis[i]/2;
(其实,这题比赛的时候没过,但是我写完了,wa在3,就很奇怪,然后比赛结束后十分钟看到了我(1<<(j-i))写成了((j-i)<<1),然后AC,吐血……哇本身一个半小时四题,第五题也可以去看看了,后面真的没发现好气啊,求今日别被hack)

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define il inline
5 #define it register int
6 #define inf 0x3f3f3f3f
7 #define lowbit(x) (x)&(-x)
8 #define mem(a,b) memset(a,b,sizeof(a))
9 #define mod 998244353
10 const int maxn=1e5+10;
11 int t,m,a,vis[81],ans[81];
12 ll n;
13 int main(){
14 scanf("%d",&t);
15 while(t--){
16 scanf("%lld",&n);scanf("%d",&m);//cout<<n<<m<<endl;
17 mem(vis,0);mem(ans,0);
18 ll sum=0;
19 for(it i=0;i<m;i++){
20 scanf("%d",&a);
21 sum+=(ll)a;
22 it c=0;while(a){a/=2;c++;}
23 vis[c]++;
24 }
25 if(sum<n){
26 printf("-1\n");
27 }
28 else{
29 ll nn=n;
30 it c=1;
31 while(nn){
32 if(nn%2){
33 ans[c]=1;
34 }
35 else{
36 ans[c]=0;
37 }
38 c++;nn/=2;
39 }
40 int an=0;
41 for(it i=1;i<=80;i++){
42 if(ans[i]){
43 if(vis[i]){
44 vis[i]--;
45 }
46 else{
47 for(it j=i+1;j<=80;j++){
48 if(vis[j]){
49 vis[j]--;vis[i]+=(1<<(j-i));an+=(j-i);break;
50 }
51 }
52 vis[i]--;
53 }
54 }
55 vis[i+1]+=vis[i]/2;
56 }
57 printf("%d\n",an);
58 }
59 }
60 return 0;
61 }
待补EFG
来源:https://www.cnblogs.com/luoyugongxi/p/12302042.html
