目录
这场出题人号称是考思维,把我给搞蒙了,把我这菜鸡实力暴露的淋漓尽致,不过这场还是让我学到了东西.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";
else
cout<<"d";
}
}
return 0;
}
写在最后:
本人实力比较菜,如有错误,欢迎指出,如果觉得看不懂,烦请参考其他大佬的思路