关于交互题&atcoder
  • 板块学术版
  • 楼主fkxr
  • 当前回复10
  • 已保存回复10
  • 发布时间2025/6/21 21:20
  • 上次更新2025/6/22 16:34:27
查看原帖
关于交互题&atcoder
995934
fkxr楼主2025/6/21 21:20

我出了一题交互题,题面如下:

有两个正整数 $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题目、排行榜打不开的?如果我不会魔法,有什么办法。

2025/6/21 21:20
加载中...