(D(博弈) E1 E2(交互))
题目:D
题意:A和U玩游戏,起始点坐标在(0,0),每一轮玩家选择将x或者y的值增加k(一定需要增加),保持增加后(p,q)距离
p
2
+
q
q
<
=
d
2
p^2+q^q<=d^2
p2+qq<=d2。谁最后不能操作谁输,输出胜利者。
画图可以发现,以k为单位划方格,无论A先手怎么走,后手可以走成一个方格,完全被包含 ( x ∗ k ) 2 (x*k)^2 (x∗k)2的正方形,后手都掌握了必胜走法,连续走两格子就改变了奇偶的。由于 2 ∗ x 2*x 2∗x必为偶数,先手必败,只需要判断一下(x+1)k是否存在。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
//#include<unordered_map>
#include<map>
#include<algorithm>
#include<queue>
#define mmp make_pair
#define inf 0x3f3f3f3f
#define llinf 0x7fffffffffffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
typedef double ld;
const ll mod=1e9+7;
const int maxn=2e5+10;
int main() {
int T;
scanf("%d",&T);
while(T--) {
ll d,k;
scanf("%lld %lld",&d,&k);
if(d==k) {
printf("Ashish\n");
continue;
}
ll ans;
for(ll i=1;;++i) {
if(i*i*k*k*2>d*d) {
ans=i-1;
break;
}
}
k*=k;
if(((ans*ans*k)+(ans+1)*(ans+1)*k)<=d*d) {
printf("Ashish\n");
}
else printf("Utkarsh\n");
}
return 0;
}
题目:E1
交互题,给定n长度的序列让你还原,你每次可以询问^,|,&,两个位置给出的位运算结果。询问不能超过n+2次。
a
+
b
=
a
a+b=a
a+b=a^
b
+
(
a
&
b
)
<
<
1
b+(a\&b)<<1
b+(a&b)<<1,与操作就相当于进位,这么表示完之后就可以解给方程组。
但是前3个解完需要6+n-3=n+3次,还必须化简一重,a[1]^a[2] , a[1]^a[3] , 那么我们不用询问2和3的异或了,直接把前两次答案异或一下。
其余的直接通过1解得。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
//#include<unordered_map>
#include<map>
#include<algorithm>
#include<queue>
#define mmp make_pair
#define inf 0x3f3f3f3f
#define llinf 0x7fffffffffffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
typedef double ld;
const ll mod=1e9+7;
const int maxn=2e5+10;
int a[75536];
int main() {
// freopen("input.txt", "r", stdin);
int n,i;
scanf("%d",&n);
int x,y,z;int x1,x2,x3,x4;
cout<<"XOR"<<" "<<1<<" "<<2<<endl;
fflush(stdout);
scanf("%d",&x1);
cout<<"AND"<<" "<<1<<" "<<2<<endl; fflush(stdout);
scanf("%d",&x2);
x=x1+x2*2;
cout<<"XOR"<<" "<<1<<" "<<3<<endl; fflush(stdout);
scanf("%d",&x3);
cout<<"AND"<<" "<<1<<" "<<3<<endl; fflush(stdout);
scanf("%d",&x4);
y=x3+x4*2;
x1=x1^x3;
cout<<"AND"<<" "<<2<<" "<<3<<endl; fflush(stdout);
scanf("%d",&x2);
z=x1+x2*2;
a[1]=(y-z+x)/2;
a[2]=x-a[1];
a[3]=z-a[2];
for(i=4;i<=n;++i) {
cout<<"XOR"<<" "<<1<<" "<<i<<endl; fflush(stdout);
scanf("%d",&x1);
a[i]=x1^a[1];
}
cout<<"!";
for(int i=1;i<=n;++i) {
cout<<" "<<a[i];
}
cout<<endl;
fflush(stdout);
// fclose(stdin);
return 0;
}
题目:E2
唯一差别在不能超过n-1次询问。
还有一个条件题目注上了黑体。。。。。
范围在[0,n-1]。
用a[1]去异或并记录,
如果没有全部用必有相同的,那么两个等式或者一个就可以求解。
继续如果没有一个相同的证明有n-1个不同的数,判断一个异或的结果是否有0,有的话a[1]与其相等,&操作即可。
否则寻找n-1,异或出的n-1必然a[1]+a[i]=n-1,任意拉上一个位置求解方程。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
//#include<unordered_map>
#include<map>
#include<algorithm>
#include<queue>
#define mmp make_pair
#define inf 0x3f3f3f3f
#define llinf 0x7fffffffffffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
typedef double ld;
const ll mod=1e9+7;
const int maxn=2e5+10;
int a[75536];
int book[maxn];
int X[75535];
int main() {
memset(book,0,sizeof(book));
int n;
scanf("%d",&n);
int pos1=-1,pos2=-1;
for(int i=2;i<=n;++i) {
printf("XOR 1 %d\n",i);
fflush(stdout);
int x;
scanf("%d",&x);
X[i]=x;
if(pos1!=-1) continue;
if(book[x]==0) {
book[x]=i;
}
else {
pos1=book[x];
pos2=i;
}
}
if(pos1!=-1) {
int x2;
printf("AND 1 %d\n",pos1); fflush(stdout);
scanf("%d",&x2);
int x=x2*2+X[pos1];
printf("AND %d %d\n",pos1,pos2); fflush(stdout);
scanf("%d",&a[pos1]);
a[1]=x-a[pos1];
}
else {
int f=-1;
for(int i=2;i<=n;++i) {
if(X[i]==0) {
f=i;
break;
}
}
if(f!=-1) {
printf("AND 1 %d\n",f); fflush(stdout);
int temp; scanf("%d",&temp);
a[1]=a[f]=temp;
}
else {
int ff;
f=book[n-1];
ff=( (f==2) ? 3 : 2 );
int xx,yy;
// 1 f ff
printf("AND 1 %d\n",ff); fflush(stdout);
scanf("%d",&xx);
int x=xx*2+X[ff];
printf("AND %d %d\n",f,ff); fflush(stdout);
scanf("%d",&yy);
int y=yy*2+(X[f]^X[ff]);
a[1]=(x-y+n-1)/2;
}
}
printf("! %d",a[1]);
for(int i=2;i<=n;++i) {
printf(" %d",X[i]^a[1]);
}
fflush(stdout);
return 0;
}
本文地址:https://blog.csdn.net/weixin_43958964/article/details/110204104