zoukankan      html  css  js  c++  java
  • Codeforces 1368F

    这题也太新颖了吧.. 交互博弈 以前一直以为交互只能出二分 

    题意:长度为n的环形灯 玩家有两种操作 结束游戏 或者选择k个灯点亮 每次这个k是玩家自己选的

       玩家操作后让电脑操作 电脑选择一个最优的点x 然后关掉从x开始的连续k个灯

       玩家想要点亮更多的灯 电脑则相反

       让你来操作 如果达到了理论上最多灯的状态就算ac了

    题解:模拟一下操作就找到规律了..

       如果玩家上一次操作点亮了k个灯 如果当前连续亮灯的最长序列为x <= k

       那么电脑操作了之后 至少会多点亮一个灯 就这样一直贪心下去.. 

       所以我们一开始枚举 最长的连续亮灯长度

       举个例子枚举的最长是2 就类似110110110.. 的把每个灯标记 1就标记为最后要点亮的灯

       再比如n=11的时候 枚举的最长=2 11011011010 注意n和1相邻一定为0

       然后模拟一下就发现这种情况 能最多点亮5个 = (n/3)*(2) + (n%3-1) - 2

       k = 7 11011011010 -> 00000001010

       k = 5 11011011010 -> 00000011010

       k = 4 11011011010 -> 00001011010

       k = 3 11011011010 -> 00011011010

       之后无论如何也不能点亮更多灯了

       然后枚举每一个长度 选一个最优的

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <map>
    #include <string.h>
    #include <string>
    using namespace std;
     
    int vis[1005];
    int now[1005];
    vector<int> g;
    int main() {
        int n;
        cin>>n;
    
        int ans = 0;
        int fz = 2;
        for(int i = 2; i <= n / 2; i++) {
            int res = (n / i) * (i - 1);
            if(n % i != 0) res += n % i - 1;
            res -= (i - 1);
            if(res > ans) ans = res, fz = i; 
        }
        //cout << ans << endl;
        for(int i = 1; i <= n; i++) if(i % fz) vis[i] = 1;
        vis[n] = 0;
        
        int lask = 0;
        int x = 0;
        while(1) {
            if(x == -1) break;
            int rr = 0;
            int pos = x;
            while(lask--) {
                now[pos] = 0;
                pos++;
                if(pos > n) pos = 1;
            }
            for(int i = 1; i <= n; i++) if(now[i]) rr++;
            
            if(rr >= ans) {
                puts("0");
                cout.flush();
                break;
            }
    
            g.clear();
            for(int i = 1; i <= n; i++) {
                if(!now[i] && vis[i]) {
                    now[i] = 1;
                    g.push_back(i);
                }
            }
            lask = g.size();
            printf("%d", lask);
            for(int i = 0; i < lask; i++) printf(" %d", g[i]); puts("");
            cout.flush();
            cin>>x;
        }
        return 0;
    }
    View Code

       

  • 相关阅读:
    Python学习笔记捌——面向对象高级编程
    Python学习笔记五,函数及其参数
    Python学习笔记四,dict和set
    Python学习笔记三,数组list和tuple
    Python学习笔记一,输入输出
    Linux 环境下自动化测试工具,Redhat dogtail的安装
    Testlink接口使用方法-python语言远程调用
    Python入门学习之input()与raw_input()的区别
    从客户端(&)中检测到有潜在危险的 Request.Path 值解决方案
    树莓派嵌入式开发第一课笔记
  • 原文地址:https://www.cnblogs.com/lwqq3/p/13162791.html
Copyright © 2011-2022 走看看