目录
1.A
2.B
3.C
4.D
5.E
这场出题人号称是考思维,把我给搞蒙了,把我这菜鸡实力暴露的淋漓尽致,不过这场还是让我学到了东西.A,B题就是签到题,会语法就能做(doge),c题我知道思路是啥,但我没想到切分出来的偶数也可能爆long long,所以还得用字符串存,自定义cmp比较函数,而我却是用long long存,用multiset排序,最后得了大部分分(泪目).D题就是分类讨论,没有清晰的头脑简直让人头皮发麻,E题是个二分图,没学过,FG太难了,不是我能涉及的.
1.A
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;cin>>n;set<int>st;for(int i=1;i<=n;i++){int t;cin>>t;if(t<=n&&t>=1)st.insert(t);}if(st.size()!=n)cout<<0;else{cout<<1<<"\n";cout<<1<<" "<<100005;}return 0;
}
2.B
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);char a,b;cin>>a>>b;if(a!=b){cout<<4<<"\n";cout<<a<<b<<"\n";cout<<b<<a<<"\n";cout<<a<<"\n";cout<<b<<"\n";}else{cout<<2<<"\n";cout<<a<<"\n";cout<<a<<a<<"\n";}return 0;
}
3.C
这题的思路就是从前向后遍历,遇到偶数就分割,(别问我可不可能出现一个奇数落单无法变成偶数的,这样这题就没答案了),然后将切割的字符串扔进一个数组,最后排个序就行
#include<bits/stdc++.h>
using namespace std;
#define int long long
bool cmp(string m,string n)
{if(m.size()!=n.size())return m.size()<n.size();else return m<n;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//遇到偶数就切割string s;cin>>s;string temp;vector<string>v;for(auto i:s){if((i-'0')%2==0){temp+=i;v.push_back(temp);temp="";}else{temp+=i;}}sort(v.begin(),v.end(),cmp);for(auto i:v){cout<<i<<"\n";}return 0;
}
4.D
首选要知道答案长啥样,因为陡峭值恰好为1,所以只能是1,1,1,2,2或2,2,1,1这两种情况(当然这里的1和2只是泛指最大值和最小值)
由此开始讨论
1.ma-mi>1,无解
2.ma-mi==1,找出最大值和最小值的分界点,如果是混乱的则无解,否则分ma在前mi在后,mi在前ma在后两种情况进行讨论,输出答案
当然,本题最恶心的是要特判全0的情况,输出2 1 1 1 ....即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;cin>>n;vector<int>v(n);int ma=-1,mi=10000000000;for(int i=0;i<n;i++){cin>>v[i];if(v[i]!=0){ma=max(ma,v[i]);mi=min(mi,v[i]);}}if(ma==-1){cout<<2<<" ";for(int i=0;i<n-1;i++)cout<<1<<" ";return 0;}//cout<<mi<<" "<<ma<<"\n";if(ma-mi>1)//最大值最小值的差超过1无解{cout<<-1;}else if(ma-mi==1)//最大值最小值的差恰好为1{vector<int>v1,v2;for(int i=0;i<n;i++){if(v[i]==mi)v1.push_back(i);//为mi的下标if(v[i]==ma)v2.push_back(i);//ma的下标}//cout<<mi<<" "<<ma<<" "<<v1[0]<<" "<<v2[0]<<"\n";if(v1.back()<v2[0]){int k;for(k=0;k<=v1.back();k++)cout<<mi<<" ";for(;k<n;k++)cout<<ma<<" ";}else if(v2.back()<v1[0]){int k;for(k=0;k<=v2.back();k++)cout<<ma<<" ";for(;k<n;k++)cout<<mi<<" ";}else{cout<<-1;}}else{if(v[0]!=0&&v[n-1]!=0){cout<<-1;}else if(v[0]==0){cout<<mi+1<<" ";for(int i=0;i<n-1;i++)cout<<mi<<" ";}else if(v[n-1]==0){for(int i=0;i<n-1;i++)cout<<mi<<" ";cout<<mi+1<<" ";}}return 0;
}
5.E
这题是个二分图,因为只有两种字符'd','p',所以每一层必须是一样的字母,而且相邻两层的字母必定不同,我们可以将奇数层打成1标记,偶数层打成0标记,那么'd'字符和'p'字符必须分别在奇数层或偶数层,
所以p的标记只能有一个,d的标记也只能有一个,不满足这种情况直接无解,反之有解,根据打的标记输出d或p即可
#include<bits/stdc++.h>//二分图
using namespace std;
#define int long long
const int maxn=1e5+5;
vector<int>g[maxn];
int dp[maxn];
void dfs(int x,int pr,int p)
{dp[x]=p;for(auto i:g[x]){if(i==pr)continue;dfs(i,x,1-p);}
}//dfs遍历树
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n;cin>>n;string s;cin>>s;s=' '+s;for(int i=0;i<n-1;i++){int u,v;cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}//建图set<int>d,p;dfs(1,0,1);for(int i=1;i<=n;i++){if(s[i]=='d')d.insert(dp[i]);if(s[i]=='p')p.insert(dp[i]);}if(d.size()>1||p.size()>1){cout<<-1;return 0;}// else if(d.size()==1&&p.size()==1&&(*d.begin()==*p.begin()))// {// cout<<-1;// }if(*d.begin()==1){for(int i=1;i<=n;i++){if(dp[i]==1)cout<<'d';else cout<<"p";}}else {for(int i=1;i<=n;i++){if(dp[i]==1)cout<<"p";elsecout<<"d";}}return 0;
}
写在最后:
本人实力比较菜,如有错误,欢迎指出,如果觉得看不懂,烦请参考其他大佬的思路