QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#698920#7703. Base Hi-Lo GamesnowythecatAC ✓2ms18844kbC++2012.0kb2024-11-01 23:02:352024-11-01 23:02:37

Judging History

你现在查看的是最新测评结果

  • [2024-11-01 23:02:37]
  • 评测
  • 测评结果:AC
  • 用时:2ms
  • 内存:18844kb
  • [2024-11-01 23:02:35]
  • 提交

answer

//must be compiled with c++20 
/*
#pragma GCC target ("avx2")
#pragma GCC optimize ("O2")
#pragma GCC optimize ("unroll-loops")
*/
#pragma GCC optimize ("unroll-loops")
#include <algorithm>
#include <bits/stdc++.h>
#include <cerrno>
#include <ext/pb_ds/assoc_container.hpp>
#include <type_traits>
using namespace __gnu_pbds;
using namespace std;
#define fasterthanlight cin.tie(0); ios::sync_with_stdio(0);
#define ll long long
#define lll __int128 
const ll inf = 1e9 + 7;
const ll inf2 = 1e9 + 9;
const ll inff= 998244353;
const ll infh = (1LL << 61) - 1;
#define pll pair<ll,ll>
#define pii pair<int,int>
#define vi vector<int>
#define vll vector<ll>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define f0(i,n) for (int i=0;i<n;i++)
#define f1(i,n) for (int i=1;i<=n;i++)
#define ff0(i,n) for (int i=n-1;i>-1;i--)
#define ff1(i,n) for (int i=n;i>0;i--)
#define fs(i,a,b) for (int i=a;i<b;i++)
#define testcases int tzxhicjkha; cin>>tzxhicjkha;while (tzxhicjkha--)
#define usingfloats cout<<setprecision(20)
#define ineedtohash mll iqknabxiopk=1;for (ll iqknabxiop=0;iqknabxiop<HASHPOWMAX;iqknabxiop++){pows[iqknabxiop]=iqknabxiopk;iqknabxiopk*=B;}
#define sz(x) ((int)(x.size()))
template <class T> auto vect(const T& v, int n) { return vector<T>(n, v); }
template <class T, class... D> auto vect(const T& v, int n, D... m) {
  return vector<decltype(vect(v, m...))>(n, vect(v, m...));
}

//2*10^6 powers for hashing
const ll HASHPOWMAX=2000005;
int msb(int n)
{
	if (n==0){
		//cout<<"F";
		return 0;
	}
    int k = __builtin_clz(n);
 
    return 31 - k;
}
ll lmsb(ll n)
{
	if (n==0){
		//cout<<"F";
		return 0;
	}
    int k = __builtin_clzll(n);
 
    return 63 - k;
}
//I have no idea if the below code is safe or good
istream &operator>>(istream &is,__int128 &v) {
    string s;
    is>>s;
    v=0;
    for(auto &it:s) if(isdigit(it)) v=v*10+it-'0';
    if(s[0]=='-') v*=-1;
    return is;
}


ostream &operator<<(ostream &os,const __int128 &v) {
    if(v==0) return (os<<"0");
    __int128 num=v;
    if(v<0) os<<'-',num=-num;
    string s;
    for(;num>0;num/=10) s.pb((char)(num%10)+'0');
    reverse(all(s));
    return (os<<s);
}

/*
template<typename T, typename Q>ostream &operator<<(ostream &os,const pair<T,Q> &v) {
    return (os<<v.first<<" "<<v.second);
}
*/

//some cursed cin vector shit
template<typename T> istream &operator>>(istream &is,vector<T> &v) {
    for (T&i:v){
        is>>i;
    }
    return is;

}
template<typename T> ostream &operator<<(ostream &os,const vector<T> &v) {
    if (v.empty()){
        return os;
    }
    for (int i=0;i<v.size()-1;i++){
        os<<v[i]<<" ";
    }
    return os<<v[v.size()-1];
}

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count()); 
//const ll B = 100;
const ll B = uniform_int_distribution<ll>(1000, inf - 1)(rng);

/*
//some cursed code
//allows int x=in;
struct {
	template<class T>
	operator T() {
		T x; std::cin >> x; return x;
	}
} in;
//breaks if string
//so do string s = (string)in;
*/

//ty Mark for modint code that I will change
template<long long MOD>
struct ModInt {
    long long v;
    ModInt() {
        v=0;
    }
    ModInt(long long _v) {
        v = _v % MOD;
        if (v < 0) {
            v += MOD;
        }
    }
 
    friend ModInt pow(ModInt base, long long exp) {
        ModInt res = 1;
        while (exp) {
            if (exp & 1) {
                res *= base;
            }
            base *= base;
            exp >>= 1;
        }
        return res;
    }
 
    ModInt &operator+=(ModInt b) {
        if ((v += b.v) >= MOD) {
            v -= MOD;
        }
        return *this;
    }
 
    ModInt &operator-=(ModInt b) {
        if ((v -= b.v) < 0) {
            v += MOD;
        }
        return *this;
    }
 
    ModInt &operator*=(ModInt b) {
        if constexpr (MOD==infh){
            //UNSAFE CODE PROBABLY
            uint64_t l1 = uint32_t(v), h1 = v >> 32;
            uint64_t l2 = uint32_t(b.v), h2 = b.v >> 32;
            uint64_t l = l1 * l2, m = l1 * h2 + l2 * h1, h = h1 * h2;
            uint64_t ret = (l & MOD) + (l >> 61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1;
            ret = (ret & MOD) + (ret >> 61);
            ret = (ret & MOD) + (ret >> 61);
            v = ret - 1;
            return *this;
        }
        else if constexpr (MOD<=INT_MAX){
            //if less than or equal to INT_MAX, lll isn't needed
            v=v * b.v % MOD;
            return *this;
        }
        else{
            v = (__int128)1 * v * b.v % MOD;
            return *this;
        }
    }

	//division is scuffed
    ModInt &operator/=(ModInt b) {
        *this *= pow(b, MOD - 2);
        return *this;
    }
 
    friend ModInt operator+(ModInt a, ModInt b) {
        return a += b;
    }
 
    friend ModInt operator-(ModInt a, ModInt b) {
        return a -= b;
    }
 
    friend ModInt operator*(ModInt a, ModInt b) {
        return a *= b;
    }
 
    friend ModInt operator/(ModInt a, ModInt b) {
        return a /= b;
    }
    
    friend istream &operator>>(istream &is, ModInt &a) {
        long long x;
        is >> x;
        a = ModInt(x);
        return is;
    }
 
    friend ostream &operator<<(ostream &os, ModInt a) {
        return os << a.v;
    }

    bool operator==(const ModInt& y) const{
        return v == y.v;
    }

    bool operator!=(const ModInt& y) const{
        return v != y.v;
    }
    ModInt& operator++() {
        v++;
        if (v == MOD) v = 0;
        return *this;
    }
    ModInt& operator--() {
        if (v == 0) v = MOD;
        v--;
        return *this;
    }
    ModInt operator++(int) {
        ModInt result = *this;
        ++*this;
        return result;
    }
    ModInt operator--(int) {
        ModInt result = *this;
        --*this;
        return result;
    }
    //bad operators for completeness sake
    bool operator>(const ModInt& y) const{
        return v > y.v;
    }
    bool operator>=(const ModInt& y) const{
        return v >= y.v;
    }
    bool operator<=(const ModInt& y) const{
        return v <= y.v;
    }
    bool operator<(const ModInt& y) const{
        return v < y.v;
    }

};
using mll = ModInt<infh>;
using mint = ModInt<inf>;
using minf = ModInt<inff>;
	


ll exp(ll x, ll n, ll m=inf) {
	assert(n >= 0);
	x %= m;  // note: m * m must be less than 2^63 to avoid ll overflow
	ll res = 1;
	while (n > 0) {
		if (n % 2 == 1) { res = res * x % m; }
		x = x * x % m;
		n /= 2;
	}
	return res;
}
ll expu(ll x, ll n) {
	assert(n >= 0);
	ll res = 1;
	while (n > 0) {
		if (n % 2 == 1) { res = res * x; }
		x = x * x;
		n /= 2;
	}
	return res;
}
mll exph(mll base, ll exp) {
    mll res = 1;
    while (exp) {
        if (exp & 1) {
            res *= base;
        }
        base *= base;
        exp >>= 1;
    }
    return res;
}
minf expf(minf base, ll exp) {
    minf res = 1;
    while (exp) {
        if (exp & 1) {
            res *= base;
        }
        base *= base;
        exp >>= 1;
    }
    return res;
}
mint expo(mint base, ll exp) {
    mint res = 1;
    while (exp) {
        if (exp & 1) {
            res *= base;
        }
        base *= base;
        exp >>= 1;
    }
    return res;
}
vector<mll> pows(HASHPOWMAX);
const mll HMODINV=exph(B,infh-2);
struct hashPart {
    mll value;
    int len;
    hashPart() {
        value=0;
        len=0;
    }
    hashPart(mll x, int y) : value(x), len(y) {}
    hashPart operator+=(hashPart b) {
        hashPart a=hashPart(value * pows[b.len] + b.value, len + b.len);
        (*this).value=a.value;
        (*this).len=a.len;
        return *this;
    }
    hashPart operator+(hashPart b) {
        return hashPart(value * pows[b.len] + b.value, len + b.len);
    }
 
    bool operator==(hashPart b) {
        return value == b.value;
    }
};
template<class T>
struct hashString {
    vector<mll> hash;
 
    hashString(T s) {
        hash.resize(int(s.size()) + 1);
        for (int i = 0; i < int(s.size()); i++) {
            hash[i + 1] = (hash[i] * B + s[i]);
        }
        while (int(pows.size()) < int(hash.size())) {
            pows.push_back(pows.back() * B);
        }
    }
 
    hashPart getHash(int l, int r) {
        return hashPart(hash[r] -hash[l] * pows[r - l], r - l);
    }
 
    hashPart getHash() {
        return getHash(0, hash.size() - 1);
    }
};


//I don't understand the below code, all I know is it's good for hashing apparently
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
ll es(ll x1, ll y1, ll x2, ll y2){
	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
ll man(ll x1, ll y1, ll x2, ll y2){
	return abs(x1-x2)+abs(y1-y2);	
}



minf choose(int n,int k){
    if (k>n){
        return 0;
    }
    minf ret=1;
    for (int i=n;i>n-k;i--){
        ret*=i;
    }
    for (int i=1;i<=k;i++){
        ret/=i;
    }
    return ret;
}
//stolen from geeks for geeks
vector<int> sieve(int n)
{
    // Create a boolean array "prime[0..n]" and initialize
    // all entries it as true. A value in prime[i] will
    // finally be false if i is Not a prime, else true.
    bool prime[n + 1];
    memset(prime, true, sizeof(prime));
 
    for (int p = 2; p * p <= n; p++) {
        // If prime[p] is not changed, then it is a prime
        if (prime[p] == true) {
            // Update all multiples of p greater than or
            // equal to the square of it numbers which are
            // multiple of p and are less than p^2 are
            // already been marked.
            for (int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
    vector<int> ret;
    // Print all prime numbers
    for (int p = 2; p <= n; p++)
        if (prime[p])
            ret.pb(p);
    return ret;
}

int base;
string ctob="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
void setup(){
    cin>>base;

}

typedef tree<double,null_type,less_equal<double>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;

void printguess(vector<int>&minpos, vector<int>&maxpos){
    for (int i=0;i<minpos.size();i++){
        char mid=(minpos[i]+maxpos[i]+1)/2;
        cout<<ctob[mid];
    }
    cout<<endl;

}
void solve(){
    bool finalguess=false;
    int d;
    cin>>d;
    vector<int> minpos(d);
    vector<int> maxpos(d,base-1);
    while (finalguess==false){
        printguess(minpos,maxpos);
        string res;
        cin>>res;
        if (res=="correct"){
            return;
        }
        for (int i=0;i<d;i++){
            int guess=(minpos[i]+maxpos[i]+1)/2;
            if (res[i]=='='){
                minpos[i]=guess;
                maxpos[i]=guess;
            }
            else if (res[i]=='+'){
                minpos[i]=min(maxpos[i],guess+1);
            }
            else{
                maxpos[i]=max(minpos[i],guess-1);
            }
        }


        bool finaly=true;
        for (int i=0;i<d;i++){
            if (minpos[i]!=maxpos[i]){
                finaly=false;
            }
        }
        finalguess=finaly;
    }
    printguess(minpos,maxpos);
    string res;
    cin>>res;
    if (res=="correct"){
            return;
    }
    else{
        cout<<"cheater"<<endl;
        cin>>res;
        return;
    }




}

signed main() {
    setup();
    //usingfloats;
	//fasterthanlight;
	//ineedtohash;
    testcases{
        solve();
    }


}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 18844kb

input:

10 2
5
----=
-=++=
==-==
correct
6
--++-+
=+-=-+
==-=-=
correct

output:

55555
22225
12445
12345
555555
228828
247819
246809

result:

ok correct (2 test cases)

Test #2:

score: 0
Accepted
time: 2ms
memory: 18776kb

input:

38 2
1
+
+
+
+
correct
3
---
+-=
--=
--=
--=
correct

output:

J
T
Y
a
b
JJJ
999
E49
C29
B19
A09

result:

ok correct (2 test cases)

Test #3:

score: 0
Accepted
time: 0ms
memory: 18760kb

input:

10 6
3
-++
--+
=-=
=-=
correct
3
-=+
-++
correct
5
++++=
+=--=
===-+
correct
4
----
====
++++
correct
4
++++
++++
====
correct
4
====
====
correct

output:

555
288
179
169
cheater
555
258
159
55555
88885
98775
98765
5555
2222
2222
cheater
5555
8888
9999
cheater
5555
5555
cheater

result:

ok correct (6 test cases)

Test #4:

score: 0
Accepted
time: 0ms
memory: 18708kb

input:

62 2
4
====
====
correct
64
================================================================
================================================================
correct

output:

VVVV
VVVV
cheater
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
cheater

result:

ok correct (2 test cases)

Test #5:

score: 0
Accepted
time: 0ms
memory: 18692kb

input:

10 10
2
-=
--
=-
=-
correct
2
-=
--
=-
=-
correct
2
-=
--
=-
=-
correct
2
-=
--
=-
=-
correct
2
-=
--
=-
=-
correct
2
-+
--
=-
=-
correct
2
--
-+
=+
=+
correct
2
--
-+
=+
=+
correct
2
--
-+
=+
=+
correct
2
--
-+
=+
=+
correct

output:

55
25
15
15
cheater
55
25
15
15
cheater
55
25
15
15
cheater
55
25
15
15
cheater
55
25
15
15
cheater
55
28
17
16
cheater
55
22
14
14
cheater
55
22
14
14
cheater
55
22
14
14
cheater
55
22
14
14
cheater

result:

ok correct (10 test cases)

Test #6:

score: 0
Accepted
time: 0ms
memory: 18760kb

input:

8 2
2
correct
2
correct

output:

44
44

result:

ok correct (2 test cases)