感想
这场比赛还是暴露了自己的许多问题,第二题因为边界没写好导致wa了半小时,所以做题的时候不能想当然,要自己想一下为什么。还有一个非常重要的地方就是要跳出固定思维模式,这是我感悟比较深的,div3如果是按照题目描述呢样想,是相当的复杂,但是仔细想一下,只要排一下序,只要前2*n个点,呢么一定可以构造出满足条件的答案。没想到在实现c题的时候,也出现了较大的失误,已经弹出了,vector的长度已经变了,怎么还可以用呢!!!
A题
A题比较好像,只要子串的左边有偶数个,右边也有偶数个就行
#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6;
int main()
{
int T;
cin>>T;
while(T--)
{
string s;
char c;
cin>>s>>c;
int l,r;
bool flag=false;
for(int i=0;s[i];i++)
{
if(s[i]==c)
{
l=i;
r=s.size()-1-i;
if(l%2==0&&r%2==0)
{
flag=true;
break;
}
}
}
if(flag) puts("Yes");
else puts("No");
}
return 0;
}
B题
可以想一下,我们可以尽量让x%a==a-1,然后再次基础上让x/a尽可能的大,因为x每增加a,才会让x/a加1,但是x每增加1我们可以让x%a加1,所以我们肯定是从大到小枚举,第一个满足x%a==a-1的,一定是最大的,但是这样会超时,我们发现,如果r%a==c,呢么r-(c+1) %a==a-1,这里需要特判一下,因为此时r-(a+1)有可能不在范围内,即小于l,这时候其实完全没有必要让余数凑成a-1了,因为凑不到a-1!而且还会让x/a和x%a都变小,所以此时的答案就是r/a+r%a。
#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6;
int main()
{
int T;
cin>>T;
while(T--)
{
ll l,r,a;
cin>>l>>r>>a;
ll d=r%a;
if(d==a-1) cout<<r/a+d<<endl;
else
{
ll x=r-(d+1);
if(x>=l) cout<<(r-(d+1))/a+a-1<<endl;
else cout<<r/a+r%a<<endl;
}
}
return 0;
}
C题
看着很难想,其实就是贪心+排序。一定要跳出思维模式!!!
#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=1e6;
struct node{
int x,v,id;
};
bool cmp1(node x,node y) {return x.v<y.v;}
bool cmp2(node x,node y) {return x.x<y.x;}
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
vector<node>v;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
v.push_back({a,b,i});
}
ll sum=0;
sort(v.begin(),v.end(),cmp1);
int len=v.size();
for(int i=0;i<len;i++)
{
if(i<2*n) sum+=v[i].v;
else v.pop_back();
}
cout<<sum<<endl;
sort(v.begin(),v.end(),cmp2);
for(int i=0,j=v.size()-1;i<j;i++,j--)
{
cout<<v[i].id<<" "<<v[j].id<<endl;
}
cout<<endl;
}
return 0;
}
D题
很好的一道模拟题,锻炼了模能力,凡是和模有关的,最好是从0~n-1 ,因为这样才方便进行模运算。
我们逆向推理一下,发现第n为一定是最后一次操作得来的,因为前n-1次操作,不会让第n未发生变化,所以我们要看最后一位进行了几次变化,从而推理出上一步的数组是什么样子的,这样类推就行。不得不说,这有点补码那意思了,把减法变成加法。
#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=2e3+100;
int a[N],b[N],mp[N],ans[N];
int n;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
mp[a[i]]=i;
}
for(int i=n;i>=1;i--)
{
int cnt;
int x=i-1,y=mp[i];
//计算需要走多少步
if(x<y) cnt=y-x;
else if(x>y) cnt=(i-1-x)+y+1;
else cnt=0;
ans[i]=cnt;
for(int j=0;j<n;j++) b[j]=a[j];
for(int j=0;j<i;j++)
{
a[(j-cnt+i)%i]=b[j];
}
for(int j=0;j<i;j++) mp[a[j]]=j;
}
for(int i=1;i<=n;i++)
{
cout<<ans[i]<<" ";
}
cout<<endl;
}
return 0;
}