A. Treasure Hunt
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int x,y,a;
cin>>x>>y>>a;
a%=(x+y);
if(a<x)
{
cout<<"NO\n";
}
else if(a<x+y)
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
}
return 0;
}
B. Pushing Balls
#include <bits/stdc++.h>
using namespace std;
char c[55][55];
int h[55][55],l[55][55];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
bool f=true;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>c[i][j];
h[i][j]=h[i][j-1]+(c[i][j]=='1');
l[i][j]=l[i-1][j]+(c[i][j]=='1');
if(c[i][j]=='1'&&h[i][j-1]!=j-1&&l[i-1][j]!=i-1)
{
f=false;
}
}
}
f==true? cout<<"YES\n":cout<<"NO\n";
}
return 0;
}
C. Dining Hall
#include <bits/stdc++.h>
using namespace std;
struct t1
{
int u,v,dis;
}t[1000005];
bool cmp(t1 a,t1 b)
{
if(a.dis!=b.dis)
{
return a.dis<b.dis;
}
if(a.u!=b.u)
{
return a.u<b.u;
}
return a.v<b.v;
}
const int dx[]={1,1,2,2};
const int dy[]={1,2,1,2};
const int d[]={0,0,0,2};
bool f[1000005];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
int tot=1;
int z=0,x=-1,y=1;
while((tot-1)/4<n)
{
while(1)
{
x++;
y--;
for(int i=0;i<4;i++)
{
t[tot+i].u=3*x+dx[i];
t[tot+i].v=3*y+dy[i];
t[tot+i].dis=t[tot+i].u+t[tot+i].v+d[i];
}
tot+=4;
if(x==z)
{
z++;
x=-1;
y=z+1;
break;
}
}
}
memset(f,false,sizeof(bool)*tot);
sort(t+1,t+tot,cmp);
int p=1,q=1;
for(int i=1;i<=n;i++)
{
int o;
cin>>o;
if(o==1)
{
while(f[p]==true)
{
p++;
}
f[p]=true;
cout<<t[p].u<<" "<<t[p].v<<"\n";
p++;
}
else
{
while(f[q]==true||!(t[q].u%3==1&&t[q].v%3==1))
{
q++;
}
f[q]=true;
cout<<t[q].u<<" "<<t[q].v<<"\n";
q++;
}
}
}
return 0;
}
D. Simple Permutation
- “构造题就这样。他让你构造一种普遍情况,你就构造特殊情况,极端情况。他说要都不等,你就递增。然后就会了”,本质上,是把不容易利用的条件(不等)转换为容易利用的条件(递增)。在本题中,就是把上取整转化为整除,考虑选取一个中间的质数,环绕它构造 p-1,p+1,p-2,p+2…的排列就好了
#include <bits/stdc++.h>
using namespace std;
int p[100005],s[100005],c[100005];
int v[10000005],prime[10000005],m;
void primes(int n)
{
for(int i=2;i<=n;i++)
{
if(v[i]==0)
{
v[i]=i;
prime[++m]=i;
}
for(int j=1;j<=m;j++)
{
if(i*prime[j]>n||prime[j]>v[i])
{
break;
}
v[i*prime[j]]=prime[j];
}
}
}
mt19937 myrand(time(NULL));
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
primes(100000);
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
iota(p+1,p+n+1,1);
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+p[i];
c[i]=s[i]/i+(s[i]%i>0);
if(v[c[i]]!=c[i]&&i!=n)
{
int cnt=100;
while(cnt--)
{
int delta=myrand()%(n-i)+1;
int j=i+delta;
s[i]=s[i-1]+p[j];
c[i]=s[i]/i+(s[i]%i>0);
if(v[c[i]]==c[i])
{
swap(p[i],p[j]);
break;
}
}
s[i]=s[i-1]+p[i];
}
}
int cnt=0;
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+p[i];
c[i]=s[i]/i+(s[i]%i>0);
cnt+=(v[c[i]]==c[i]);
}
for(int i=1;i<=n;i++)
{
cout<<p[i]<<" ";
}
cout<<endl;
}
return 0;
}
E1. Canteen (Easy Version)
- rotate 函数进行元素范围上的左旋转
- 具体而言,std::rotate 交换范围 [first, last) 中的元素,将 [first, middle) 中的元素放在 [middle, last) 后面并且保留这两个范围中元素的原本顺序,如:
rotate(a.begin(), a.begin() + x, a.end())
- 遇见环形结构,首先断环为链考虑
- 然后,关于归零点就是第一个前缀和小于 b 数组的点,应当是挺显然的结论,可是你在赛场上居然没看出来,还是被出题人绕进去了呀…
- 一个有趣的视角是,可以把题目中的操作视为括号匹配
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[200005],b[200005],c[400005];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
c[i+n]=c[i]=b[i]-a[i];
}
int p=0,ans=0,cur=0;
for(int i=1;i<=n;i++)
{
while(p<i)
{
p++;
cur+=c[p];
}
while(cur<0)
{
p++;
cur+=c[p];
}
ans=max(ans,p-i+1);
cur-=c[i];
}
cout<<ans<<"\n";
}
return 0;
}