QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#698920 | #7703. Base Hi-Lo Game | snowythecat | AC ✓ | 2ms | 18844kb | C++20 | 12.0kb | 2024-11-01 23:02:35 | 2024-11-01 23:02:37 |
Judging History
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();
}
}
详细
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)