小牧心情不好,还想接着写点东西,那就再写一次训练的题目解析吧
A题
思维题,简单搞一搞
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的数组,最多每个位置只能改变一次(就是当前值和前面的数交换),求改变后的最小字典序
思路:我们从后往前开始遍历尽可能把小的数往前穿,然后每个穿的位置都标记一下,再把没有穿的位置判断一下,看看可不可以在交换一下,不可以是就输出了
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题
题意:给出一个河的跨度n,有m个木板,以及没可以跳的跨度,给出m个数,表示木板长度还有跳的宽度d输出所有木板的位置,没有木板的地方输出0
思路;先把所有的水域求出来,就是没有木板的长度,然后每个木板,最多可以跳m+1次,因此如果水域k >(d-1)*(m+1),就过不了河,否则可以过河,每隔min(d-1,k/(m+1))个水域加一道木板
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <string> #include <algorithm> #include <map> #include <vector> #include <queue> using namespace std; typedef long long ll; int a[1010]; int main() { int n,m,d; cin >> n >> m >> d; int sum=0; for(int i=1;i<=m;i++) { cin >> a[i]; sum+=a[i]; } int q = ceil((n-sum)*1.0/(m+1)); if((d<=q)) { cout<<"NO"<<endl; return 0; } else{ cout << "YES"<<endl; int num =1; for(int i= 1;i<=m;i++) { int j = min(d-1,n-sum); for(int k=0;k<j;k++) cout<<0<<' '; for(int k=0;k<a[i];k++) { cout<<num<<' '; } num++; sum+=j; } } for(int i=0;i<n-sum;i++)cout<<0<<' '; return 0; }
D题
题意:给你一个长度为n的0,1序列,可以交换m次,只能相邻的可以交换,求经过交换后得到的最小字典序数列
思路;我们就是要经过m次交换尽可能的把0调到最前面
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; int main() { int q; cin >> q; while(q--) { ll n,d; cin >> n >> d; string s; cin >> s; ll num=0,cun=0; int end_i=0,end_j=0; for(int i = 0 ;i<n;i++) { if(s[i]=='0') { num +=(i-cun); s[i]='1'; cun++; //cout << num<<endl; if(num>d) { //cout<<"sfew"<<endl; cun--; num-=i-cun; d=d-num; s[i]='1'; end_i=i-d; s[i-d]='0'; break; } } } // cout <<cun<<"wfw"<<endl; //if(cun) //cout << cun<<endl; for(int i=0;i<cun;i++)cout<<0; for(int i=cun;i<n;i++) { cout<<s[i]; } cout<<endl; } return 0; }