牛客练习赛140(A~C)

A-袋鼠将军的密码

签到题。

 1 #include <iostream>
 2 using namespace std;
 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
 4 
 5 int main(int argc, char** argv) {
 6     int T;
 7     cin>>T;
 8     while(T--){
 9         int n,m;
10         cin>>n>>m;
11         string s;
12         cin>>s;
13         if(n<m) cout<<-1<<endl;
14         else cout<<s.substr(0,m)<<endl;    
15     }
16     return 0;
17 }
View Code

B-袋鼠将军的传送门

一个数轴,不能<=0或>n,三个操作,+1,-1或者跳到floor(n/x),x为当前位置。

直觉考虑最多只会使用一次操作3,证明可见官方题解。那么判断n和s的关系即可,若s|n,则res=n/s-1+1,若是n不能整除s,则有两种情况。

从floor(n/s)执行操作3再一步一步加到s,或者从floor(n/2)+1执行操作3,再一步一步减到s。

除此之外,还有就是别忘了能够直接从1走到s。

 1 #include<iostream>
 2 using namespace std;
 3 typedef long long LL;
 4 int main(){
 5     int T;
 6     cin>>T;
 7     while(T--){
 8         LL n,s;
 9         cin>>n>>s;
10         LL t=max(0ll,n/s);
11         LL ans=s-1;
12         if(t*s==n){
13             ans=min(ans,t-1+1);
14         }else{
15             LL l=n/(t+1),r=n/t;
16             ans=min(ans,t+1-1+1+s-l);
17             ans=min(ans,t-1+1+r-s);
18         }
19         cout<<ans<<endl;
20     }
21     return 0;
22 }
View Code

C-构造题

MEX定义为一个序列最小未出现的非负整数,一次操作定义为将序列中的一个数替换成MEX值,给定一个序列,问能否将全0的序列通过操作变为这个序列。

因为MEX的定义,给定序列中肯定不能有除0以外的相同的两个数,此外,每次操作只能将MEX值覆盖一个值,所以序列中从0到最大能缺失两个或以上。

比如0 1 1 2,因为存在两个相同的非零数,不可构造。再比如0 0 2 4,缺失1 3,当序列操作到0 0 2 3时,MEX值为1,不可构造。

至于构造过程,从目标序列向全0推进,每次将序列中最大的数替换为前一个缺失的值,如果没有缺失,则替换为0。

 1 //构造题
 2 #include<iostream>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 const int N = 110;
 7 int q[N];
 8 int op[N][N];
 9 int n;
10 bool check(){
11     //不能有除0以外的相同数字
12     bool st[N];
13     memset(st,0,sizeof st);
14     int maxx=-1;
15     for(int i=0;i<n;i++){
16         if(st[q[i]]&&q[i]!=0)
17             return false;
18         st[q[i]]=true;
19         maxx=max(maxx,q[i]);
20     }
21     //直到最大的值不能有两个或以上缺失
22     int cnt=0;
23     for(int i=0;i<=maxx;i++){
24 //         cout<<i<<" "<<st[i]<<endl;
25         if(!st[i])
26             cnt++;
27     }
28     return cnt<2;
29 }
30 bool all_zero(int t){
31     for(int i=0;i<n;i++){
32         if(op[t][i]!=0)
33             return false;
34     }
35     return true;
36 }
37 //构造操作序列,每次找到最大值,替换成缺失的,如果没有缺失的就替换成0
38 vector<int> fun(){
39     vector<int> res;
40     for(int i=0;i<n;i++){
41         op[0][i]=q[i];
42     }
43     int cnt=1;
44     while(!all_zero(cnt-1)){
45         memcpy(op[cnt],op[cnt-1],sizeof op[0]);
46         int maxx=-1,id;
47         bool st[N];
48         memset(st,0,sizeof st);
49         for(int i=0;i<n;i++){
50             st[op[cnt][i]]=true;
51             if(op[cnt][i]>maxx)
52                 maxx=op[cnt][i],id=i;
53         }
54         int miss=-1;
55         for(int i=0;i<=maxx;i++){
56             if(st[i]==false){
57                 miss=i;
58                 break;
59             }
60         }
61         if(miss==-1)
62             op[cnt][id]=0;
63         else
64             op[cnt][id]=miss;
65         res.push_back(id+1);
66         cnt++;
67     }
68     return res;
69 }
70 int main(){
71     int T;
72     cin>>T;
73     while(T--){
74         cin>>n;
75         for(int i=0;i<n;i++){
76             cin>>q[i];
77         }
78         if(!check()){
79             cout<<-1<<endl;
80         }else{
81             vector<int> res=fun();
82             cout<<res.size()<<endl;
83             for(int i=res.size()-1;i>=0;i--){
84                 cout<<res[i]<<" ";
85             }
86             cout<<endl;
87         }
88     }
89     return 0;
90 }
View Code

 

posted on 2025-06-09 22:27  greenofyu  阅读(17)  评论(0)    收藏  举报