2019雅礼集训 D10T2 硬币翻转 [交互题]

题目描述:

coin.h:

#include<string>
void guess();
int ask(std::string coin);

grader.cpp:

#include "coin.h"
#include <iostream>
#include <assert.h>

using namespace std;

namespace U {
    using u64 = unsigned long long;
    using i64 = long long;

    static struct random_t {
        u64 s0, s1;
        random_t(){
            s0 = 0x0123456789abcdef;
            s1 = 0xfedcba9876543210;
        }
        random_t(u64 s0, u64 s1):s0(s0), s1(s1){}
        u64 get(){
            std::swap(s0, s1);
            s1 ^= s1 << 23, s1 ^= (s1 >> 17) ^ s0 ^ (s0 >> 26);
            return s0 + s1;
        }
        int randint(int L, int R){
            return get() % (R - L + 1) + L;
        }
    } rnd;

    static int Test;
    static string coin;
    static int queries;

    struct info{};

    int ask(string guess){
        ++queries;
        assert(guess.size() == 100);
        int ret = 0, x;
        for (x = 0; x < 100; ++x) {
            assert(guess[x] == ‘0‘ || guess[x] == ‘1‘);
            if (guess[x] == coin[x]) {
                ++ret;
            }
        }
        if (ret == 100) {
            throw info();
        }
        x = rnd.randint(0, 99);
        if (guess[x] == coin[x]) {
            coin[x] ^= 1;
        }
        return ret;
    }

    static int test;
    static string loc[105];

    void main(){
        cin >> rnd.s0 >> rnd.s1;
        cin >> Test;
        for (test = 1; test <= Test; ++test) {
            cin >> loc[test];
        }
        fclose(stdin);
        double answer = 100;
        for (test = 1; test <= Test; ++test) {
            double point = 0;
            coin = loc[test];
            assert(coin.size() == 100);
            try {
                guess();
            } catch (info suc) {
                if (queries <= 200) point = 100;
                else if (queries <= 600) point = 120 - 0.15 * queries;
                else point = 36 - 0.01 * queries;
                if (point < 0) point = 0;
                queries = 0;
            }
            answer = min(answer, point);
            if (answer == 0) break;
        }
        puts("auhrouahrbahdfnaldkssafbaufnianfiamofmaf");
        printf("%.2lf\n", answer);
    }
}

int ask(string guess){return U::ask(guess);}
int main(){U::main();}


简单交互题,不做解释,直接放题解

标程:

#include "coin.h"
#include <string>

void guess(){
    srand(23333);
    std::string s = "";
    int cnt, ncnt, x;
    for (x = 0; x < 100; ++x) {
        s += (rand() & 1) + ‘0‘;
    }
    cnt = ask(s);
    for (x = 0; x < 100; ++x) {
        while (true) {
            s[x] ^= 1;
            ncnt = ask(s);
            if (cnt > ncnt) break;
            cnt = ncnt;
        }
        cnt = ncnt;
    }
    for (x = 0; x < 100; ++x) {
        s[x] ^= 1;
    }
    ask(s);
}

原文地址:https://www.cnblogs.com/p-b-p-b/p/10279264.html

时间: 2024-10-10 14:18:42

2019雅礼集训 D10T2 硬币翻转 [交互题]的相关文章

2019雅礼集训 D7T1 inverse [概率/期望,DP]

题目描述: 样例: input1: 3 1 1 2 3 output1: 833333340 input2: 5 10 2 4 1 3 5 output2: 62258360 数据范围与约定: 概率/期望的常用套路:将许许多多个元素单独考虑,以达到解决问题的目的. 这里发现不可能整个序列一起考虑,于是枚举任意两个位置,计算出k次翻转之后左边大于右边的概率,再加起来就好了. 于是我们有了一个非常暴力的DP: 令\(dp(i,j,k)?\) 表示k次翻转之后i位置大于j位置的概率.为了方便我们强行令

2019雅礼集训 D4T1 w [费用流]

题目描述: 样例: input1: 4 1 2 1 2 3 4 1 2 1 3 3 4 1 2 2 3 1 4 2 1 3 4 1 1 2 3 output1: 9 input2: 5 1 1 3 99 99 100 2 1 2 1 3 3 4 3 5 1 3 1 2 2 4 2 5 2 1 2 3 1 2 1 2 2 1 output2: 198 数据范围: 先放个原题地址:CF1061E. 毒瘤出题人搬原题差评 毒瘤出题人题目翻译出锅差评 这题看到如此不伦不类的问法,似乎不是dp.贪心等算法

【2019雅礼集训】【第一类斯特林数】【NTT&amp;多项式】permutation

目录 题意 输入格式 输出格式 思路: 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a,b<=n 输入格式 输入三个整数n,a,b. 输出格式 输出一个整数,表示答案. 思路: 这道题是真的神啊... 首先,根据官方题解的思路,首先有一个n^2的DP: 定义dp[i][j]表示一个长度为i的排列,从前往后数一共有j个数字大于所有排在它前面的数字. 首先有转移式: \[dp[i][j]=d

2019雅礼集训 D7T2 subsequence [DP,平衡树]

题目描述: 样例: input1: 5 -2 -8 0 5 -3 output1: 5 10 13 2 -13 input2: 6 -10 20 -30 40 -50 60 output2: 60 160 280 390 400 210 数据范围与约定: 考虑DP:令\(dp(i,j)\)表示前\(i\)个点选\(j\)个,能得到的最大价值. 得到转移方程:\(dp(i,j)=\max\{dp(i-1,j),dp(i-1,j-1)+a_i\cdot j\}\) 这个方程很明显是\(n^2\)的.

2019雅礼集训 D10T1 数字重排 [DP]

题目描述: 样例: input: 5 5 5 10 17 23 output: 3 数据范围与约定: 简单DP,不做解释,直接搬题解. 标程: #include<bits/stdc++.h> using namespace std; const int N=1e5+5; int n,a[N],m,s; bitset<N>f,g; int main(){ freopen("sort.in","r",stdin); freopen("s

#6030. 【雅礼集训 2017 Day1】矩阵

#6030. 「雅礼集训 2017 Day1」矩阵 题目描述 有一个 n×n  的矩阵,每个位置 (i,j) 如果是 . 表示为白色,如果是 # 表示为黑色. 初始时,每个位置可以是黑色或白色的,(i,j)  位置的值会作为 ai,j 给你. 现在有一种操作,选择两个整数 i,j∈[1,n],记 (i,1),(i,2),…,(i,n) (i, 1), (i, 2)的颜色为 C1,C2,…Cn ??,将 (1,j),(2,j),…,(n,j)  的颜色赋为 C1,C2,…,Cn ??. 你的任务是

「6月雅礼集训 2017 Day10」quote

[题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. $1 \leq T \leq 10^5, 1 \leq n \leq 10^7, 1\leq K \leq 10^9$ [题解] 显然引号序列可以看做括号序列,于是我们有了一个$O(n^2)$的dp了. 设$f_{i,j}$表示到第$i$个位置,前面有$j$个左引号没有匹配,的方案数 每次,要么有

LOJ #6035.「雅礼集训 2017 Day4」洗衣服 贪心

这道题的贪心好迷啊~我们对于两个过程进行单独贪心,然后再翻转一个,把这两个拼起来.先说一下单独贪心,单独贪心的话就是用一个堆,每次取出最小的,并且把这个最小的加上他单次的,再放进去.这样,我们得到的结果,是对于某些洗衣机,不停地洗,然后把这些洗衣机的时间,混在一起,排个序,由于对于每个洗衣机,如果被用到,那么他就会被不停地用,如果我们稍作改动,就一定会是用小的换来大的,所以这样最优.我们把两个拼起来为什么是对的呢.对于两个单独的答案,最优的无疑是,翻转之后拼起来,因为如果不是这样,也就是说进行了

雅礼集训——day1、day2

day1: 嗯上午考试拿了100分.第一题40,第二题60.看完题的时候我就觉得第二题的部分分是最好得到的,因为数据范围只有300,而且一眼看上去就是网络流的二分图多重匹配模型?然后就建了个网络流写了些,期望得分是70分,但是第1组数据有点劲,被卡掉了,就拿了60分.正解是map+set的贪心...并不会STL 写完T2去看T1,先用DFS乱搞了一下,结果样例都没过去,我手推了一下样例,得到了一个公式,就是从一个点出发需要加上的边数=这个点通过DFS能够遍历到的点的个数-与这个点直接相连的点的个