A. Alex and a Rhombus
规律思维
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define FI first
#define S second
const int M = 1e5 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int a[110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
a[1]=1;
for(int i=2;i<=100;i++)
a[i]=a[i-1]+(i-1)*4;
cout<<a[n]<<endl;
return 0;
}
B |
发现:x==-(-(x+1))+1.所以每个数有2种取值,贪心即可。
优先让所有数乘积为正。然后优先让数绝对值尽可能大
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 1e5 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int a[M];
int z[M];
int f[M];
int pr[M];
pii p[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
int num=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>=0)
z[i]=a[i],f[i]=a[i]+1;
else f[i]=-a[i],z[i]=-a[i]-1;
p[i].F=max(z[i],f[i]),p[i].S=i;
if(p[i].F==f[i])
num++;
}
// cout<<num<<" "<<endl;
if(num%2==0)
{
for(int i=1;i<n;i++)
if(p[i].F==z[i])
cout<<z[i]<<" ";
else
cout<<-f[i]<<" ";
if(p[n].F==z[n])
cout<<z[n]<<endl;
else
cout<<-f[n]<<endl;
return 0;
}
sort(p+1,p+1+n);
for(int i=n;i>=1;i--)
{
if(p[i].F==f[p[i].S])
{
p[i].F--;
// cout<<p[i].F<<" --"<<i<<endl;
break;
}
}
for(int i=1;i<=n;i++)
pr[p[i].S]=p[i].F;
for(int i=1;i<n;i++)
if(pr[i]==z[i])
cout<<z[i]<<" ";
else
cout<<-f[i]<<" ";
if(pr[n]==z[n])
cout<<z[n]<<endl;
else
cout<<-f[n]<<endl;
return 0;
}
C. Valeriy and Deque
先用双端队列模拟第一轮,记录。
然后发现后面数组顺序不会发生变化。
输出即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 2e5 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int a[M];
ll p[M];
pii id[M];
deque<int> dq;
int pr[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,q;
cin>>n>>q;
int ma=-INF;
for(int i=1;i<=n;i++)
cin>>a[i],ma=max(a[i],ma),dq.push_back(a[i]);
for(int i=1;i<=q;i++)
cin>>p[i];
ll mod=n-1;
ll time=0;
while(dq.front()!=ma)
{
int A=dq.front();
dq.pop_front();
int B=dq.front();
dq.pop_front();
dq.push_front(max(A,B));
dq.push_back(min(A,B));
time++;
id[time].F=A,id[time].S=B;
}
dq.pop_front();
int cnt=0;
while(!dq.empty())
{
pr[++cnt]=dq.front();
dq.pop_front();
}
for(int i=1;i<=q;i++)
{
if(p[i]<=time)
cout<<id[p[i]].F<<" "<<id[p[i]].S<<endl;
else
{
ll now=(p[i]-time)%mod;
if(now==0)now=mod;
cout<<ma<<" "<<pr[now]<<endl;
}
}
return 0;
}
/*
2 6
1 2
1 2 3 4 5 6
*/
D. Tolik and His Uncle
构造题。
我们发现:每次跳斜对角,跳的横坐标和纵坐标之差一直不会重复。
所以我们直接按这个输出坐标就行。
可以现在纸上画画,找到规律再输出会方便很多,用cin会T!!!;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 1e6 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
//map<int,int>mp[M<<1],mmp[M<<1];
int main()
{
/* ios::sync_with_stdio(false);
cin.tie(0);*/
int n,m;
cin>>n>>m;
if(n==1)
{
for(int i=1;i<=n*m;i++)
{
if(i&1)
printf("1 %d\n",(i+1)/2);
else
printf("1 %d\n",m-i/2+1);
}
return 0;
}
int x1=1,y1=1,x2=n,y2=m,flag1=1,flag2=1,tag1=0,tag2=0;
for(int i=1;i<=n*m;i++)
{
// cout<<i<<endl;
if(i&1)
{
printf("%d %d\n",x1,y1);
//cout<<x1<<" "<<y1<<endl;
if((x1==n||x1==1)&&tag1)
{
flag1^=1;
y1++;
tag1=0;
continue;
}
if(flag1)x1++;
else x1--;
tag1=1;
}
else
{
printf("%d %d\n",x2,y2);
//cout<<x2<<" "<<y2<<endl;
if((x2==n||x2==1)&&tag2)
{
flag2^=1;
y2--;
tag2=0;
continue;
}
if(flag2)x2--;
else x2++;
tag2=1;
}
}
return 0;
}
E. Serge and Dining Room
每个人都会买自己能买的菜中最贵的菜,所以先后顺序并不影响结果。
问最后剩的菜最贵的是多少。如果不剩 输出-1.
因为每个人只能买一道,而且买自己所能买的最贵的菜。所以我们可以用区间覆盖表示一个人的购买力。
即:一个人有x元,那就在1--x区间-1,一道菜y元,就在1--y区间-1。处理所有菜和人后,如果最后整个区间有大于0的数,那就说明有剩的菜。输出最大的大于0的数,即最后剩的菜,没有则输出-1.
上述操作可以用权值线段树来做。区间更新+区间查询大于0且最大的数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 1e6 + 10;
const int N = 1e6+9;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int st[M<<2],lazy[M<<2],a[M],b[M];
void pushdown(int l,int r,int rt)
{
if(lazy[rt]!=0)
{
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
st[rt<<1]+=lazy[rt];
st[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
}
void update(int l,int r,int rt,int x,int y,int d)
{
//printf("%d %d-/-/-/----%d %d %d %d\n",x,y,l,r,rt,st[rt]);
if(x<=l&&r<=y)
{
lazy[rt]+=d;
st[rt]+=d;
return ;
}
pushdown(l,r,rt);
//printf("%d %d--- %d %d\n",l,r,st[rt<<1],st[rt<<1|1]);
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,rt<<1,x,y,d);
if(y>mid) update(mid+1,r,rt<<1|1,x,y,d);
st[rt]=min(st[rt<<1],st[rt<<1|1]);
}
int query(int l,int r,int rt)
{
if(l==r)
{
if(l==1&&st[rt]>=0)
return -1;
return l;
}
pushdown(l,r,rt);
int mid=(l+r)>>1;
//printf("%d %d--- %d %d\n",l,r,st[rt<<1],st[rt<<1|1]);
if(st[rt<<1|1]<0)return query(mid+1,r,rt<<1|1);
return query(l,mid,rt<<1);
}/*
int Query(int l,int r,int rt,int x,int y)
{
if(x<=l&&r<=y)
{
return st[rt];
}
pushdown(l,r,rt);
int mid=(l+r)>>1;
int A=INF,B=INF;
if(x<=mid)A=Query(l,mid,rt<<1,x,y);
if(y>mid)B=Query(mid+1,r,rt<<1|1,x,y);
return min(A,B);
}*/
int main()
{
/*ios::sync_with_stdio(false);
cin.tie(0);*/
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
update(1,N,1,1,a[i],-1);
// printf("%d -aaaaaaa- %d\n",query(1,N,1),Query(1,N,1,1,N));
}
for(int i=1;i<=m;i++)
{
scanf("%d",&b[i]);
update(1,N,1,1,b[i],1);
// printf("%d -bbbbb- %d\n",query(1,N,1),Query(1,N,1,1,N));
}
// printf("%d -cc- %d\n",query(1,N,1),Query(1,N,1,1,N));
int q,c,x,y;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&c,&x,&y);
if(c==1)
{
// printf("%d--- %d\n",a[x],y);
update(1,N,1,1,a[x],1);
update(1,N,1,1,y,-1);
a[x]=y;
}
else
{
// printf("%d--- %d\n",b[x],y);
update(1,N,1,1,b[x],-1);
update(1,N,1,1,y,1);
b[x]=y;
}
printf("%d\n",query(1,N,1));
}
return 0;
}