------------恢复内容开始------------
从今天开始我要每天都要做一波div3来提高自己的思维,,,,
A题
题意:给你a个n元的,b个1元的硬币,问你可不可以组成S元
思路:就是看看s最大可以用几个n元的,剩下的都要用一元的来补
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 6 using namespace std; 7 int main() 8 { 9 int q; 10 scanf("%d",&q); 11 while(q--) 12 { 13 int a,b,n,s; 14 scanf("%d%d%d%d",&a,&b,&n,&s); 15 int d = s/n; 16 int p = s - min(d,a)*n; 17 if(b>=p){ 18 printf("YES "); 19 } 20 else{ 21 printf("NO "); 22 } 23 } 24 }
B题
题意:给你n个数,你可以进行n-1次(前提每个i位置的操作,只有一次,也就是可以从1——n-1每个点只能操作一次)操作(就是交换第i和第i+1 两个数的位置),问经过这么多次的操作,输出可能的最小字典序
思路:倒着从后往前,将最小的数尽可能的往前交换,而且每个位置交换一次,循环交换,之到不可以交换位置为止
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <cmath> 6 #include <algorithm> 7 8 using namespace std; 9 typedef long long ll; 10 int main() 11 { 12 int q; 13 cin >> q; 14 while(q--) 15 { 16 int n; 17 int a[110],b[110]; 18 cin >> n; 19 for(int i=1;i<=n;i++) 20 { 21 scanf("%d",&a[i]); 22 b[i]=0; 23 } 24 int d =n-1; 25 while(d) 26 { 27 int flag =0; 28 for(int i=n;i>1;i--) 29 { 30 if(a[i]<a[i-1]&&b[i-1]==0) 31 { 32 int t=a[i-1]; 33 a[i-1]=a[i]; 34 a[i]=t; 35 d--; 36 b[i-1]=1; 37 flag=1; 38 if(d==0)break; 39 } 40 } 41 if(!flag||!d)break; 42 } 43 for(int i=1;i<n;i++) 44 { 45 printf("%d ",a[i]); 46 } 47 printf("%d ",a[n]); 48 } 49 return 0; 50 }
C题(第一波没有写出)
题意:有m个木板,有一个n个宽度的河,每次可以跳d距离,问可不可以跳过去,跳的过去的话,就把每个木板的位置表现出来
思路:贪心处理每个空隙(每次都是(跳的最大距离和剩余水宽)的最小值),跳一次紧跟木板,最后如果水还有,就把所有水都输出
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 #include <string> 6 #include <algorithm> 7 #include <map> 8 #include <vector> 9 #include <queue> 10 11 using namespace std; 12 typedef long long ll; 13 int a[1010]; 14 int main() 15 { 16 int n,m,d; 17 cin >> n >> m >> d; 18 int sum=0; 19 for(int i=1;i<=m;i++) 20 { 21 cin >> a[i]; 22 sum+=a[i]; 23 } 24 int q = ceil((n-sum)*1.0/(m+1)); 25 if((d<=q)) 26 { 27 cout<<"NO"<<endl; 28 return 0; 29 } 30 else{ 31 cout << "YES"<<endl; 32 int num =1; 33 for(int i= 1;i<=m;i++) 34 { 35 int j = min(d-1,n-sum); 36 for(int k=0;k<j;k++) 37 cout<<0<<' '; 38 for(int k=0;k<a[i];k++) 39 { 40 cout<<num<<' '; 41 } 42 num++; 43 sum+=j; 44 } 45 } 46 for(int i=0;i<n-sum;i++)cout<<0<<' '; 47 return 0; 48 }
D题
题意:给你一个字符串(只含有1,0),长度为N,一个操作数d,输出经过操作后的最小字典序
思路:判断每个零的位置,将他尽可能往前移动
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <cmath> 6 #include <algorithm> 7 8 using namespace std; 9 typedef long long ll; 10 int main() 11 { 12 int q; 13 cin >> q; 14 while(q--) 15 { 16 ll n,d; 17 cin >> n >> d; 18 string s; 19 cin >> s; 20 ll num=0,cun=0; 21 int end_i=0,end_j=0; 22 for(int i = 0 ;i<n;i++) 23 { 24 if(s[i]=='0') 25 { 26 num +=(i-cun); 27 s[i]='1'; 28 cun++; 29 //cout << num<<endl; 30 if(num>d) 31 { 32 //cout<<"sfew"<<endl; 33 cun--; 34 num-=i-cun; 35 d=d-num; 36 s[i]='1'; 37 end_i=i-d; 38 s[i-d]='0'; 39 break; 40 } 41 } 42 } 43 // cout <<cun<<"wfw"<<endl; 44 //if(cun) 45 //cout << cun<<endl; 46 for(int i=0;i<cun;i++)cout<<0; 47 for(int i=cun;i<n;i++) 48 { 49 cout<<s[i]; 50 } 51 cout<<endl; 52 } 53 return 0; 54 }
------------恢复内容结束------------