Problem - A - Codeforces
大致思路:题目说每一个问题后面必须有大于等于1个回答,但是有时候会有问题还没来得及回答的时候,所以说我们只要判断从后往前回答的数量要大于或者是等与问题的数量就好了。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
map<char,int>mp;
cin>>t;
while(t--)
{
mp.clear();
int n;
cin>>n;
string s;
cin>>s;
int flag=0;
for(int i=n-1;i>=0;i--)
{
mp[s[i]]++;
if(mp['Q']>mp['A'])
{
cout<<"No\n";
flag=1;
break;
}
}
if(!flag) cout<<"Yes\n";
}
return 0;
}
总结:做题目的时候需要多想一下是不是包含了所有的可能性,如果说最后是以问题结束的了,如果说只是前面回答的多一些,后面的问题没有得到解答呢。
Problem - B - Codeforces
题目大致意思就是说要使得相邻元素之间的差的最小值最大,不难想到去拆分大数和小数。
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int n;
cin>>n;
int a[1010];
if(n%2==0)
{
int m=n;
for(int pos=1,i=n/2;pos<=n;pos+=2,i--)
a[pos]=i,a[pos+1]=m--;
}
else
{
int zh=n/2+1;
int m=zh+1;
a[n]=zh;
for(int pos=1,i=1;pos<=n;pos+=2,i++)
a[pos]=i,a[pos+1]=m++;
}
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<endl;
return ;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
总结:考虑周到一点,三思而后行,争取一次就对。
Problem - C1 - Codeforces
错误思路:合并每一个连续的区间,如果说是奇数个,就加上元素的值,如果说是偶数个,就直接跳过了,之和就为0。但是有一个bug:1 -1 -1 1 -1 -1 -1 -1,这样就不对了。
正确思路:如果说是奇数个,就可以直接输出-1,因为合并对总的序列之和的奇偶性不产生影响,;如果说是偶数个,两两合并,如果说两个数相等,可以合并成一个区间,之和就为0,如果说两个数不一样,就可以分开,之和还是为0。
//要使得总和之和等于0
//如果说是连着的相同的数可以直接忽略不计
//如果说是奇数个,就绝对不行
//如果说是偶数个,
//连续的数可以合并
/*#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int a[N];
int l[N],r[N];
int n;
void solve()
{
cin>>n;
int anss=0;
for(int i=1;i<=n;i++) cin>>a[i];
int ans=0;
int pos=1;
int cnt=1;
for(int i=2;i<=n;i++)
{
if(a[i]==a[i-1]) cnt++;
else
{
l[++anss]=pos;
r[anss]=i-1;
if(cnt%2)//奇数个
{
if(a[i-1]==1) ans+=1;
else ans-=1;
}
pos=i;
cnt=1;
}
}
l[++anss]=pos;
r[anss]=n;
if(cnt%2)//奇数个
{
if(a[n]==1) ans+=1;
else ans-=1;
}
if(ans) cout<<-1<<endl;
else
{
cout<<anss<<endl;
for(int i=1;i<=anss;i++)
cout<<l[i]<<' '<<r[i]<<endl;
}
return ;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
} */
//错例
//8
//1 -1 -1 1 -1 -1 -1 -1
#include<bits/stdc++.h>
using namespace std;
int a[200010];
int l[200010],r[200010];
void solve()
{
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++) cin>>a[i];
if(n%2==1) cout<<-1<<endl;
else
{
for(int i=2;i<=n;i+=2)
{
if(a[i]==a[i-1])
{
l[++ans]=i-1;
r[ans]=i;
}
else
{
l[++ans]=i-1;
r[ans]=i-1;
l[++ans]=i;
r[ans]=i;
}
}
cout<<ans<<endl;
for(int i=1;i<=ans;i++)
cout<<l[i]<<' '<<r[i]<<endl;
}
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
总结:思考全面,找到数之间的关系。
Problem - C2 - Codeforces
思路:可以先思考一下0的作用,0可以使得算式数字前面的符号发生改变,也就是说说可以改变区间内部的值,所以说我们可以先把非0元素的下标挑出来,同样,如果说是奇数,就可以直接输出-1,然后退出就好了。如果说是偶数个,两两归类,如果说两个数相等,那么这个时候就需要讨论如果说两个数下标奇偶性相同,则需要分成两个区间,如果说奇偶性不相同,可以直接放在一个区间里面就行,如果说两个不一样,则相反。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
vector<pair<int,int> >v;
int n,t;
int a[N];
void slove(){
cin>>n;
int t1=0,t2=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==1)t1++;
else if(a[i]==-1)t2++;
}
if((t1+t2)%2){
cout<<"-1"<<endl;
return ;
}
for(int i=1;i<n;i++){
bool flag=false;
if(t1==t2){
v.push_back({i,i});
flag=true;
}
else if(t1>t2){
if(a[i+1]==1){
v.push_back({i,i+1});
t1--;
t2++;
i++;
flag=true;
}
}
else if(t1<t2){
if(a[i+1]==-1){
v.push_back({i,i+1});
t1++;
t2--;
i++;
flag=true;
}
}
if(!flag)v.push_back({i,i});
}
int s=v.size();
if(v[s-1].second!=n)v.push_back({n,n});
cout<<v.size()<<endl;
for(int i=0;i<v.size();i++){
cout<<v[i].first<<" "<<v[i].second<<endl;
}
}
int main(){
cin>>t;
while(t--){
v.clear();
slove();
}
}
总结:可以多琢磨一下。找一下数据之间的关系和规律。
Problem - D - Codeforces
大致思路,如果说a [ i ]小于x,那么他的数量就必须要是i+1的倍数,这样才不会有剩余的可以取模,且需要往上合并。
#include<bits/stdc++.h>
using namespace std;
const int N=500010;
int a[N];
int b[N];
int main()
{
int n,x;
cin>>n>>x;
int minn=500010;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[a[i]]++;
minn=min(minn,a[i]);
}
for(int i=minn;i<x;i++)
{
if(b[i]%(i+1))
{
cout<<"No\n";
return 0;
}
b[i+1]+=b[i]/(i+1);//合并
}
cout<<"Yes\n";
return 0;
}