我出了一题交互题,题面如下:
有两个正整数 $1\le x,y\le10^9$,你必须将它猜出来。
每次查询,你可以选择两个数 $a,b(a\ne b,1\le a,b\le 10^9)$,你会从交互库得到 $\gcd(x+a,y+b)$。
你要在 $1000$ 次猜测之内(包括确定答案的询问)得到 $x,y$。
# 交互格式
每次猜测时格式为 $?~a~b$,此时你将得到 $\gcd(x+a,y+b)$。
当你确定答案,你可以输出 $!~x~y$,然后立即结束程序。
这是它的interactor
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char ** argv){
registerInteraction(argc, argv);
int x = inf.readInt(),y= inf.readInt();
cout.flush();
int left = 1000;
bool found = false;
while(left > 0 && !found){
left --;
char ch=ouf.readChar();
int a = ouf.readInt(1, 1000000000);
int b = ouf.readInt(1, 1000000000);
if(ch=='!'){
if(a!=x||b!=y){
quitf(_wa, "couldn't guess the true number");
}
found=1;
break;
}
if(ch!='?'){
quitf(_wa, "read %c",ch);
}
if(a==b)quitf(_wa, "read %d, %d",a,b);
cout<<__gcd(a+x,b+y)<<endl;
cout.flush();
}
if(!found)
quitf(_wa, "couldn't guess the number with 1000 questions");
quitf(_ok, "guessed the number with %d questions!", 1000 - left);
}
这是deepseek的代码:
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {
if (b == 0) return a;
return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
if (a == 0 || b == 0) return 0;
return (a / gcd(a, b)) * b;
}
ll extended_gcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
ll x1, y1;
ll d = extended_gcd(b, a % b, x1, y1);
x = y1;
y = x1 - y1 * (a / b);
return d;
}
pair<ll, ll> merge_congruences(ll r1, ll m1, ll r2, ll m2) {
if (m1 == 0 || m2 == 0) {
return make_pair(0, -1);
}
if (m1 == 1) {
return make_pair(r2 % m2, m2);
}
if (m2 == 1) {
return make_pair(r1 % m1, m1);
}
ll g = gcd(m1, m2);
ll r_diff = r2 - r1;
if (r_diff % g != 0) {
return make_pair(0, -1);
}
ll m1_norm = m1 / g;
ll m2_norm = m2 / g;
ll t = r_diff / g % m2_norm;
if (t < 0) t += m2_norm;
ll inv, k;
ll g_inv = extended_gcd(m1_norm, m2_norm, inv, k);
if (g_inv != 1) {
return make_pair(0, -1);
}
inv = (inv % m2_norm + m2_norm) % m2_norm;
ll k0 = t * inv % m2_norm;
ll x0 = r1 + k0 * m1;
ll m_combined = m1 / g * m2;
x0 = x0 % m_combined;
if (x0 < 0) x0 += m_combined;
return make_pair(x0, m_combined);
}
vector<ll> get_divisors(ll n) {
vector<ll> divisors;
if (n == 1) {
divisors.push_back(1);
return divisors;
}
for (ll i = 1; i * i <= n; i++) {
if (n % i == 0) {
divisors.push_back(i);
if (i != n / i) {
divisors.push_back(n / i);
}
}
}
sort(divisors.begin(), divisors.end());
return divisors;
}
int main() {
ll r_y = 0, m_y = 1;
ll y0 = -1;
int count_query = 0;
const int max_rounds_phase1 = 40;
for (int round = 0; round < max_rounds_phase1; round++) {
ll a_i = round + 1;
ll b1 = 1000 + 2 * round + 1;
ll b2 = 1000 + 2 * round + 2;
cout << "? " << a_i << " " << b1 << endl;
count_query++;
ll g1;
cin >> g1;
cout << "? " << a_i << " " << b2 << endl;
count_query++;
ll g2;
cin >> g2;
if (g1 <= 0 || g2 <= 0) {
continue;
}
ll residue1 = (-b1 % g1 + g1) % g1;
pair<ll, ll> cong1 = merge_congruences(r_y, m_y, residue1, g1);
if (cong1.second == -1) {
cong1 = make_pair(r_y, m_y);
}
ll residue2 = (-b2 % g2 + g2) % g2;
pair<ll, ll> cong2 = merge_congruences(cong1.first, cong1.second, residue2, g2);
if (cong2.second == -1) {
continue;
}
r_y = cong2.first;
m_y = cong2.second;
if (m_y > 1000000000LL) {
y0 = r_y % m_y;
if (y0 < 1) y0 += m_y;
if (y0 > 1000000000LL) {
y0 = (r_y - m_y) % m_y;
if (y0 < 1) y0 += m_y;
}
break;
}
}
if (y0 == -1) {
y0 = r_y % m_y;
if (y0 == 0) {
y0 = m_y;
}
if (y0 < 1 || y0 > 1000000000LL) {
y0 = r_y - m_y;
if (y0 < 1 || y0 > 1000000000LL) {
y0 = (r_y % m_y);
if (y0 == 0) y0 = m_y;
}
}
}
ll M = y0 + 1;
vector<ll> divisors = get_divisors(M);
sort(divisors.rbegin(), divisors.rend());
ll L_x = 1;
ll r_x = 0;
int max_queries_phase2 = 200 - count_query;
int count_phase2 = 0;
for (ll d : divisors) {
if (count_phase2 >= max_queries_phase2) {
break;
}
if (L_x > 1000000000LL) {
break;
}
if (d == 1) {
continue;
}
if (L_x % d == 0) {
continue;
}
ll a_val = d - (r_x % d);
if (a_val <= 0) {
a_val += d;
}
if (a_val == 1) {
a_val += d;
}
if (a_val > 1000000000LL) {
continue;
}
cout << "? " << a_val << " " << 1 << endl;
count_phase2++;
count_query++;
ll g;
cin >> g;
if (g <= 0) {
continue;
}
ll new_r = (-a_val % g + g) % g;
pair<ll, ll> res_x = merge_congruences(r_x, L_x, new_r, g);
if (res_x.second == -1) {
continue;
}
r_x = res_x.first;
L_x = res_x.second;
}
ll x0 = r_x % L_x;
if (x0 <= 0) {
x0 += L_x;
}
if (x0 < 1 || x0 > 1000000000LL) {
x0 = (r_x % L_x);
if (x0 <= 0) x0 += L_x;
}
cout << "! " << x0 << " " << y0 << endl;
return 0;
}
我感觉没啥输出格式的问题,但PE Expected integer, but "?" found
,这是怎么回事?
还有就是有没有和我一样atcoder题目、排行榜打不开的?如果我不会魔法,有什么办法。