2018.8.22 练习赛

  • T1 井字棋
  • 题意:给定一井字棋残局,问结果
  • 状压记忆化暴搜,博弈
  •   1 #include<stdio.h>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 int po[20],ch[256];
      7 int f[100000][3];
      8 int judge(int s)
      9 {
     10     int g[10];
     11     for(int i=1,ss=s;i<=9;i++,ss/=3) g[i]=ss%3;
     12     if(g[1]==g[2]&&g[2]==g[3])
     13     {
     14         if(g[1]==1) return 1;
     15         if(g[1]==2) return -1;
     16     }
     17     if(g[4]==g[5]&&g[5]==g[6])
     18     {
     19         if(g[4]==1) return 1;
     20         if(g[4]==2) return -1;
     21     }
     22     if(g[7]==g[8]&&g[8]==g[9])
     23     {
     24         if(g[7]==1) return 1;
     25         if(g[7]==2) return -1;
     26     }
     27     if(g[1]==g[4]&&g[4]==g[7])
     28     {
     29         if(g[1]==1) return 1;
     30         if(g[1]==2) return -1;
     31     }
     32     if(g[2]==g[5]&&g[5]==g[8])
     33     {
     34         if(g[2]==1) return 1;
     35         if(g[2]==2) return -1;
     36     }
     37     if(g[3]==g[6]&&g[6]==g[9])
     38     {
     39         if(g[3]==1) return 1;
     40         if(g[3]==2) return -1;
     41     }
     42     if(g[1]==g[5]&&g[5]==g[9])
     43     {
     44         if(g[1]==1) return 1;
     45         if(g[1]==2) return -1;
     46     }
     47     if(g[3]==g[5]&&g[5]==g[7])
     48     {
     49         if(g[3]==1) return 1;
     50         if(g[3]==2) return -1;
     51     }
     52     return 0;
     53 }
     54 int cnt(int s){int ret=0;for(int i=1;i<=9;i++,s/=3) ret+=(s%3==0); return ret;}
     55 int dfs(int s,int who)
     56 {
     57     if(judge(s)!=0) return judge(s);
     58     else if(cnt(s)==0) return judge(s);
     59     if(~f[s][who]) return f[s][who];
     60     int mmin=1,mmax=-1;
     61     if(who==1)
     62     {
     63         for(int i=1,ss=s;i<=9;i++,ss/=3)
     64         {
     65             int t=ss%3;
     66             if(t==0) mmax=max(mmax,dfs(s+po[i-1],2));
     67         }
     68         return f[s][who]=mmax;
     69     }
     70     else
     71     {
     72         for(int i=1,ss=s;i<=9;i++,ss/=3)
     73         {
     74             int t=ss%3;
     75             if(t==0) mmin=min(mmin,dfs(s+po[i-1]*2,1));
     76         }
     77         return f[s][who]=mmin;
     78     }
     79 }
     80 int main()
     81 {
     82     memset(f,-1,sizeof(f));
     83     po[0]=1,ch[‘X‘]=2,ch[‘O‘]=1,ch[‘_‘]=0;
     84     for(int i=1;i<=10;i++) po[i]=po[i-1]*3;
     85     int T;
     86     scanf("%d",&T);
     87     while(T--)
     88     {
     89         int st=0,fc=0,sc=0;
     90         char buf[5];
     91         for(int i=1;i<=3;i++)
     92         {
     93             scanf("%s",buf);
     94             for(int j=0;j<3;j++)
     95             {
     96                 st+=ch[buf[j]]*po[(i-1)*3+j];
     97                 if(buf[j]==‘O‘) fc++;
     98                 else if(buf[j]==‘X‘)sc++;
     99             }
    100         }
    101         int win=0;
    102         if(fc==sc) win=dfs(st,1);
    103         else win=dfs(st,2);
    104         printf("%s\n",win==0?"E":win==1?"O":"X");
    105     }

  • T2 ?asuchy
  • 题面:
  • (BZOJ)3749: [POI2015]?asuchy

    Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special Judge
    Submit: 420  Solved: 164
    [Submit][Status][Discuss]

    Description

    圆桌上摆放着n份食物,围成一圈,第i份食物所含热量为c[i]。

    相邻两份食物之间坐着一个人,共有n个人。每个人有两种选择,吃自己左边或者右边的食物。如果两个人选择了同一份食物,这两个人会平分这份食物,每人获得一半的热量。

    假如某个人改变自己的选择后(其他n-1个人的选择不变),可以使自己获得比原先更多的热量,那么这个人会不满意。

    请你给每个人指定应该吃哪一份食物,使得所有人都能够满意。

    Input

    第一行一个整数n(2<=n<=1000000),表示食物的数量(即人数)。食物和人都从1~n编号。

    第二行包含n个整数c[1],c[2],…,c[n](1<=c[i]<=10^9)。

    假设第i个人(1<=i<n)左边是第i份食物,右边是第i+1份食物;而第n个人左边是第n份食物,右边是第1份食物。

    Output

    如果不存在这样的方案,仅输出一行NIE。

    如果存在这样的方案,输出一行共n个整数,第i个整数表示第i个人选择的食物的编号。如果有多组这样的方案,输出任意一个即可。

    Sample Input

    5
    5 3 7 2 9

    Sample Output

    2 3 3 5 1

  • 状态恶心的dp,状态:f[i][j]表示第i个食物处于第j种状态:被左边吃,被右边吃,被两边吃,两边都不吃,转移见code(ps:不存在无解的情况!)话说似乎贪心+随机化之类可以骗到大部分分……多跑几遍说不定就A了……
  •  1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #define ll long long
     5 using namespace std;
     6
     7 ll n;
     8 ll a[1000005];
     9 ll f[1000005][5];
    10 ll ans[1000005];
    11 // 1 left
    12 // 2 right
    13 // 3 yiqi
    14 // 4 doubu
    15
    16 bool dp(ll v) {
    17     memset(f,0,sizeof(f));
    18     f[1][v]=1;
    19     for(int i=2; i<=n; i++) {
    20         if(f[i-1][1]&&a[i-1]<=2*a[i]) f[i][1]=1;
    21         if(f[i-1][1]&&a[i-1]<=a[i]) f[i][3]=1;
    22         if(f[i-1][2]&&a[i-1]*2>=a[i]) f[i][2]=2;
    23         if(f[i-1][2]&&a[i-1]>=a[i]) f[i][4]=2;
    24         if(f[i-1][3]&&a[i-1]>=a[i]*2) f[i][4]=3;
    25         if(f[i-1][3]&&a[i-1]>=a[i]) f[i][2]=3;
    26         if(f[i-1][4]&&a[i-1]<=a[i]) f[i][1]=4;
    27         if(f[i-1][4]&&a[i-1]*2<=a[i]) f[i][3]=4;
    28     }
    29     if(!f[n][v]) return 0;
    30     for(int i=n; i>=1; i--) {
    31         if(v==1) ans[i-1]=(i-1)%(n-1)+1;
    32         if(v==2) ans[i]=(i-1)%(n-1)+1;
    33         if(v==3) ans[i-1]=ans[i]=(i-1)%(n-1)+1;
    34         v=f[i][v];
    35     }
    36     for(int i=1; i<n; i++) printf("%lld ",ans[i]);
    37     return 1;
    38 }
    39
    40 int main() {
    41     scanf("%lld",&n);
    42     for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
    43     a[++n]=a[1];
    44     for(int i=1;i<=4;i++) if(dp(i)) return 0;
    45 }

  • T3 泰拉瑞亚
  • 题意:完成两个操作:单点增加某点的值,快速查找某点左右两边第一个比它值大的点。
  • 这道真是毒瘤题……大概思路……分块维护块中单调栈,每个块再用线段树维护单点修改……代码暂无……

原文地址:https://www.cnblogs.com/KatouKatou/p/9520747.html

时间: 2024-08-30 09:21:44

2018.8.22 练习赛的相关文章

三级菜单的增删改-2018.2.22(下)

百度了一下三级菜单增删改的代码,要我说呢,这个代码要我自己写呢,估计几天也写不出来,这个代码写的,怎么说呢,非常巧妙,然后呢 我把他的代码拷贝下来自己看了一遍然后修改了一遍 算是比他原来的要更加好一点了吧(当然是我认为了)还有就是现在感觉他里面有些代码我看不懂 它的用处,也不知道是真的没用,还是我真的没看懂,这是一个问题,不管了吧 反正算是修改好了,好了 . 他的代码: f_read = open('menu_file','r',encoding='utf8') #读取menu_file文件中的

2018.4.22

2018.4.22 早. 说是要记录一下每一天的东西,但实际上已经好几天没有写了. 早上起来发现下雨了,原本准备早上起来去上自习把算法设计写了, 看来只能窝在宿舍里了(其实是犯懒 昨天有开始了久违的跑步,希望能坚持下去=.= 蓝桥杯和数模比赛时间冲突了,只能放弃数模了,说实话心里有点不爽 希望今天能把算法设计的作业写了,再复习一下. 就这样,溜了溜了 原文地址:https://www.cnblogs.com/DLKKILL/p/8905862.html

2018.09.22 上海大学技术分享 - An Introduction To Go Programming Language

老实说笔者学习 Go 的时间并不长,积淀也不深厚,这次因缘巧合,同组的同事以前是上海大学的开源社区推动者之一,同时我们也抱着部分宣传公司和技术分享的意图,更进一步的,也是对所学做一个总结,所以拟定了这次分享.另外与会的同学大多都是大二大三的"萌新",考虑到受众水平和技术分享的性质,所以实际上这次分享涉及到的知识点都相对基础,当然为了寓教于乐,本人也十分讨厌着重介绍基础语法时可能引起的枯燥,所以加了少少的私货,并且也针对 1.11 及之前版本中或优雅,或局限的特性做了发散性的讲解. 总而

2018.1.22 7周1次课

七周一次课(1月22日) 10.1 使用w查看系统负载 10.2 vmstat命令 10.3 top命令 10.4 sar命令 10.5 nload命令 众所周知,生病了需要去医院看病,大夫首先要询问我们哪里不舒服,然后再通过观察和自己的经验,大体上就能判定我们得的是什么病.然而Linux不会说话,它不会主动告诉我们哪里出现了问题,需要我们自己去观察.那么如何评估系统运行状态是否良好呢?下面阿铭就介绍一些帮我们分析系统状态的工具. 10.1 使用w查看系统负载 相信所有Linux管理员最常用的命

三级菜单的增删改-2018.2.22(上)

1.首先把字典内容存到txt文档里面 2.读取txt文本内容以及用eval将文本转化为字典 3.可以看出来昨天写的三级菜单并不适用今天要使用的增删改 #_author_:"Bushii" #data:2018/2/21 menu= { '山东' : { '青岛' : ['四方','黄岛','崂山','李沧','城阳'], '济南' : ['历城','槐荫','高新','长青','章丘'], '烟台' : ['龙口','莱山','牟平','蓬莱','招远'] }, '江苏' : { '苏

2018.3.22 一周四次课

SELinux临时关闭:setenforce 0SELinux永久关闭:vi /etc/selinux/config 进入编辑文件找到SELINUX=enforcing这一行,输入"i"进入编辑模式,修改为SELINUX=disabled,按ESC,然后输入wq保存退出,重启系统. 1.1 单用户模式 (只允许在物理机操作) 重启linux有三种命令: 1)reboot 2)init 6 3)init 0 关机 4)shutdown -r now 1.1 首先要重启linux rebo

2018.3.22 13周4次课

十三周四次课(3月22日) 13.1 设置更改root密码 13.2 连接mysql 13.3 mysql常用命令 13.1 设置更改root密码 root用户的mysql的超级管理员用户,跟linux的root用户类似.但需要区分,这个root用户和系统的root用户不是一个用户,需要注意.也可以创建一个普通用户来连接mysql 首次进入mysql数据库是不用密码的.默认mysql数据库的root用户密码为空,连接时不需要密码 设置密码: 启动mysql:service mysqld star

2018.8.18练习赛

HDU 2089 不要62 数据量比较小,还是直接暴力吧. 1 #include<stdio.h> 2 int a[1000010]; 3 int F(int m); 4 int main() 5 { 6 int i,sum,n,m; 7 for(i=1;i<=1000000;i++) 8 a[i]=F(i); 9 while(scanf("%d%d",&n,&m)!=EOF) 10 { 11 if(n==0&&m==0) 12 bre

2018.8.23 练习赛

T1 三级包 题意:带数量限制的0/1背包问题,但是容量极大,没办法dp. 正解是分为两部分状态压缩:但是实际上暴搜加上卡时(100000000)就能过 1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<ctype.h> 6 using namespace std; 7 int f[50][50]; 8 int n