强行进行遍历更改会超时,其实我们只需要检索一下不该出现某个字母i的位置是否出现了i。例如字母a在1号位置,那么2,4,6.......号位置就不能出现a。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<cmath>
using namespace std;
int t;
void solve()
{
int n;
string s;
cin>>n;
cin>>s;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j+=2){
if(s[i]==s[j]){
cout<<"No"<<endl;
return;
}
}
}
cout<<"Yes"<<endl;
return;
}
int main()
{
cin>>t;
while(t--) solve();
return 0;
}
暴力解决的复杂度是n*q,明显有点大了,(暴力之前第一件事就是看数据大小!!!什么题都直接暴力只会白扣50昏)
区间内进行变动,很容易想到前缀和。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cmath>
using namespace std;
int t;
void solve()
{
int n,q;
cin>>n>>q;
int a[n+2];
int sum[n+2];
memset(a,0,sizeof(a));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++){
cin>>a[i];
if(i==1) sum[i]=a[i];
else sum[i]=sum[i-1]+a[i];
}
while(q--){
int l,r,k;
cin>>l>>r>>k;
int s=sum[l-1]+sum[n]-sum[r]+(r-l+1)*k;//前缀和把复杂度降到O(1)
//cout<<s<<endl;
if(s%2) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
int main()
{
cin>>t;
while(t--) solve();
return 0;
}
PS:一定要记得把测试数据删除干净
重点题

由于有四种方向,代表四个不同的状态,一共有n*m个格子,所以一共有4*n*m个不同的状态,我们使用一个三维数组表示小球目前所在位置的状态:vis[x][y][d],x,y表示坐标,d表示方向。
之后模拟小球的运动,while循环,直到到达目标位置或者出现相同状态时退出循环。
模拟小球运动的最关键点是小球的方向问题,一共有四个方向,而且是右上右下左上左下这样的对角线方向,题解中提供了一个非常厉害而且通用的表示方向的方法:d由0,1,2,3四个数字组成,分别表示四个方向:DL、UL、DR、UR,发现:有D的即方向向下的 %2==0,反之!=0;有L的<2,反之>=2
而且我们知道:碰撞到左右两边的时候,上下的方向是不改变的;碰撞到上下两边的时候,左右的方向是不改变的;
接下来就是简单的模拟一遍,由于数据不是很大,模拟一边不会超时。
#include <bits/stdc++.h>
using namespace std;
int t;
void solve()
{
int n,m,x1,y1,x2,y2;
string s;
cin>>n>>m>>x1>>y1>>x2>>y2;
x1--;y1--;x2--;y2--;
cin>>s;
int d=(s[0]=='U'? 1+(s[1]=='R'? 2 : 0) : 0+(s[1]=='R'? 2 : 0));//d表示方向
bool vis[n][m][4];
memset(vis,false,sizeof(vis));
int x=x1,y=y1;
int ans=0;
while(!vis[x][y][d])
{
//cout<<"x="<<x<<" y="<<y<<" d="<<d<<endl;
if(x==x2&&y==y2){
cout<<ans<<endl;
return;
}
int tb=0;//暂时记录反弹次数
//讨论碰撞边界情况
if(x==0&&d%2==1){
d--;
tb++;
}
if(x==n-1&&d%2==0){
d++;
tb++;
}
//到达上下的边界时 改变的是U和D R和L的属性并不改变
if(y==0&&d<2){
d+=2;
tb++;
}
if(y==m-1&&d>=2){
d-=2;
tb++;
}
ans+=min(1,tb);//每次最多反弹一次
//tb=2时表示走到四个顶点了进行反弹
if(vis[x][y][d]) break;
vis[x][y][d]=true;
if(d>=2) y++;
else y--;
if(d%2==1) x--;
else x++;
}
cout<<-1<<endl;
}
int main()
{
cin>>t;
while(t--) solve();
return 0;
}