codeforces #598 div3题解

A:

 1 A.A payment without change
 2 #include<iostream>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 int main(){
 9     int q;
10     cin>>q;
11     while(q--){
12         ll a,b,n,s;
13         cin>>a>>b>>n>>s;
14         if(a*n>s){
15             ll t=s/n;
16             ll num=s-t*n;
17             if(num<=b)cout<<"YES"<<endl;
18             else cout<<"NO"<<endl;
19         }else{
20             ll num=s-a*n;
21             if(num<=b)cout<<"YES"<<endl;
22             else cout<<"NO"<<endl;
23         }
24     }
25 
26     return 0;
27 }
View Code

B:

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e3+10;
 6 int main(){
 7     int n;
 8     cin>>n;
 9     while(n--){
10         vector<int>num;
11         num.clear();
12         int pos[maxn];
13         int vis[maxn];
14         memset(pos,0,sizeof(pos));
15         memset(vis,0,sizeof(vis));
16         int m;
17         cin>>m;
18         for(int i=0;i<m;i++){
19             int t;
20             cin>>t;
21             num.push_back(t);
22             pos[t]=i;//表示的是t的位置为i
23         }
24         for(int i=1;i<=m;i++){
25             //int flag=1;
26             while(1){//为的是可以持续的往前面更换数字。
27                 if(pos[i]>0&&vis[pos[i]-1]==0){//前面一个还没有被访问过,那么先访问一下
28                     vis[pos[i]-1]=1;
29                     int now=pos[i],pnow=pos[i]-1;//now与pnow都是结点的下标
30                     swap(num[now],num[pnow]);
31                     //cout<<"Ok"<<i<<endl;
32                     swap(pos[num[now]],pos[num[pnow]]);//注意数字更换之后,这个数字的下标也是需要更换的,
33                     //因为如果只更换数字的话,下标是存放在另外的一个数组,另外一个数组内部的元素并没有改变,所以地址下标也要改变,
34                 }else{
35                     break;
36                 }
37             }
38             vis[pos[i]]=1;//这个结点的位置彻底结束了,之后可以不用再考虑这个结点所在的位置了。。。
39             //cout<<pos[i]<<endl;
40         }
41         for(int i=0;i<num.size();i++){
42             cout<<num[i]<<" ";
43         }
44         cout<<endl;
45     }
46     
47     return 0;
48 }
View Code

C:

 1 //解法一:贪心,就是将板子先全部放在一端,之后要跳且q跳的距离不够长,那么拿一个板子过来
 2 
 3 #include<iostream>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<algorithm>
 7 using namespace std;
 8 int main(){
 9     int n,m,d;
10     vector<int>num(10000,0);
11     cin>>n>>m>>d;
12     int sum=0;
13     for(int i=0;i<m;i++){
14         int t;
15         cin>>t;
16         num[i]=t;
17         sum+=t;
18     }
19     if(sum+(m+1)*(d-1)<n){//m+1表示的是m个板子之间拥有m+1个间隙,d-1表示的是当前在这个板子上也是算距离的,所以减一
20         cout<<"NO"<<endl;
21         return 0;//直接结束完事
22     }
23     cout<<"YES"<<endl;
24     int x=n-sum;//表示还需要跳多远,就是在没有m板子的情况下,需要t裸跳多远
25     int pos=0;
26     int now=0;
27     while(now<n){
28         int jump=min(d-1,x);//一定小取两者的最小值,因为可能不需要板子可以直接跳过去,但是题目有一个数据---->10 1 11 1
29         //表示不需要板子也可以直接跳过去,但是输出位置不能全是0,所以一定要取最小值
30         now+=jump;
31         x-=jump;
32         for(int i=0;i<jump;i++){
33             cout<<0<<" ";
34         }
35         while(num[pos]--){//表示还有几个可以输出的是pos+1。。。
36             cout<<pos+1<<" ";
37             now++;//表明当前已走过的距离大小,木板已走过的路径也是需要加的
38         }
39         pos++;
40     }
41     cout<<endl;
42     return 0;
43 }
View Code

D:

 1 #include <cstdio>
 2 #include<iostream>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 void swap(char& a,char& b){
 7     char temp=a;
 8     a=b;
 9     b=temp;
10 }
11 typedef long long ll;
12 int main(){
13     int n;
14     cin>>n;
15     while(n--){
16         ll m,k;
17         string s;
18         cin>>m>>k;
19         cin>>s;
20         ll first=0;
21         for(ll i=0;i<m;i++){
22             if(s[i]=='1'){
23                 first=i;
24                 break;
25             }
26         }
27         for(ll i=first+1;i<m;i++){
28             if(s[i]=='0'){
29                 if(i-first<=k){
30                     swap(s[i],s[first]);
31                     k=k-(i-first);
32                     first++;//这个表示下一个可以换的位置。。。
33                 }else{
34                     swap(s[i],s[i-k]);//最好的情况只需要换一次就结束了,因为之后没有可以再走的步骤了。。。
35                     break;
36                 }
37             }
38         }
39         cout<<s<<endl;
40 
41     }
42 
43 
44     return 0;
45 }
View Code

E:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<vector>
 6 #include<algorithm>
 7 #include<cstring>
 8 using namespace std;
 9 typedef long long ll;
10 const ll maxn=1e6;
11 ll dp[maxn];//dp存放的是最终的结果,就是当前位置求得的和是多少。。。
12 pair<ll,ll>a[maxn];//存放输入的数据,以及当前数据的下标。
13 ll cnt[maxn];//这个是存放下标的!!!
14 int main(){
15     
16     int n;
17     cin>>n;
18     for(int i=1;i<=n;i++){
19         ll num;
20         cin>>num;
21         a[i].first=num;//第一个位置存放的是数据
22         a[i].second=i;//第二个位置存放的是位置下标,这个是不能变的,因为这样方便后面的操作
23     }
24     sort(a+1,a+1+n);
25     dp[0]=0;
26     for(int i=1;i<=n;i++){
27         dp[i]=1e12;
28         for(int d=3;d<=min(i,5);d++){//d<=min(i,5)这是为了防止前面i=1,2,3,4,5设置的。。当等于上述值得时候,不需要任何操作的
29             dp[i]=min(dp[i],dp[i-d]+a[i].first-a[i-d+1].first);//注意这里是i-d+1而不是i-d一定不能错。。。
30         }
31     }//这样状态转移就完成啦。。。
32     cout<<dp[n]<<" ";
33     int N=0;
34     for(int i=n;i>0;){
35         for(int d=3;d<=min(i,5);d++){//如果当前是划分的情况话,那么加一
36             if(dp[i]==dp[i-d]+a[i].first-a[i-d+1].first){
37                 N++;
38                 for(int j=1;j<=d;j++){
39                     cnt[a[i-j+1].second]=N;//从后向前标注,当前结点所在的队伍的队号。
40                 }
41                 i=i-d;
42                 break;//一个区间只能是3,4,5这其中的一种,所以出现则break。结束
43             }
44         }
45     }
46     cout<<N<<endl;
47     for(int i=1;i<=n;i++){
48         cout<<cnt[i]<<" ";
49     }
50     cout<<endl;
51     return 0;
52 }
View Code

猜你喜欢

转载自www.cnblogs.com/zb121/p/12520188.html
今日推荐