zoukankan      html  css  js  c++  java
  • 10.29 模拟赛

    再次爆炸.模拟赛

    T1 defile

    题目大意:

    假你本回合拥有 M 个随从且均可以攻击,其中第 i 个随从的攻击力为 A2[i],生命值为 B2[i]  对手拥有N个随从,其中第i个随从的攻击力为 A1[i],生命值为B1[i]

    每次可以选择一个属于你的攻击力不为0 且未攻击过的随从攻击对手的某个未死亡的随从,每次攻击后双方的随从各受到等同于敌人攻击力的伤害

    亵渎: 对所有随从造成 1 点伤害,若有随从死亡,则重新释放该法术 如果释放后 所有随从均死亡,则成功打出了一次“教科书般的亵渎

    求能否通过操作随从指定的敌方随从来达成一次“教科书般 的亵渎”

    思路:

    爆搜  但是忘了攻击力不能为0的随从才能攻击

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 15
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 //yyc score=0
    22 int n,m,a[MAXN][2],b[MAXN][2],hsh[MAXN<<1],vis[MAXN],ok;
    23 int cheque()
    24 {
    25     memset(hsh,0,sizeof(hsh));ok=0;
    26     for(int i=1;i<=n;i++) hsh[a[i][0]]=1,ok|=(a[i][0]>0); for(int i=1;i<=m;i++) hsh[a[i][1]]=1,ok|=(a[i][1]>0);
    27     if(!ok) return 1;
    28     if(!hsh[1]) return 0;
    29     for(int i=2;i<=25;i++) if(hsh[i]&&!hsh[i-1]) return 0;
    30     return 1;
    31 }
    32 void dfs(int x)
    33 {
    34     //for(int i=1;i<=n;i++) cout<<a[i][0]<<" ";puts("");
    35     //for(int i=1;i<=m;i++) cout<<a[i][1]<<" ";puts("
    ");
    36     if(cheque()) {puts("Yes");exit(0);}
    37     if(x==m+1) return ;
    38     if(b[x][1]>0)
    39     {
    40         for(int i=1;i<=n;i++)
    41             if(a[i][0]>0)
    42             {
    43                 a[i][0]-=b[x][1],a[x][1]-=b[i][0];
    44                 dfs(x+1);
    45                 a[i][0]+=b[x][1],a[x][1]+=b[i][0];
    46             }
    47     }
    48     dfs(x+1);
    49 }
    50 int main()
    51 {
    52     freopen("defile.in","r",stdin);
    53     freopen("defile.out","w",stdout);
    54     n=read(),m=read();
    55     for(int i=1;i<=n;i++) b[i][0]=read(),a[i][0]=read();
    56     for(int i=1;i<=m;i++) b[i][1]=read(),a[i][1]=read();
    57     dfs(1);puts("No");
    58 }
    View Code

    T2 treasure

    题目大意:

    一个寻宝游戏的目的是在有限的时间内寻到尽量多的宝藏

    游戏的地图是一个n行m列的网格,每个网格可能是“.”、“#”、“*”、“S”四种字符的一 种,分别表示空地、障碍、宝藏点和玩家位置

    角色每秒可以向上下左右移动一格,不能走出边界或走到障碍上

    当走到了一个宝藏点时,她可以瞬间收集这里的宝藏

    共有T + 0.5秒时间行动,当时间截至游戏就会结束。求游戏结束之前收 集尽量多的宝藏(即到达的不同的宝藏点尽量多)

    思路:

    每个宝藏点bfs求一下距离

    状压水题

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 101010
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 //yyc score=0
    22 int n,m,k,T,x[20],y[20],dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    23 char mp[520][520];
    24 int qx[260010],qy[260010],l,r,ans;
    25 int vis[520][520],dis[24][24],dp[1<<17][17];
    26 int ok(int a,int b) {return a&&b&&a<=n&&b<=m&&(mp[a][b]!='#');}
    27 void bfs(int t)
    28 {
    29     qx[l=r=1]=x[t],qy[1]=y[t];
    30     memset(vis,0,sizeof(vis));int a,b;
    31     while(l<=r)
    32     {
    33         a=qx[l],b=qy[l++];
    34         for(int i=0;i<4;i++)
    35             if(ok(a+dx[i],b+dy[i])&&!vis[a+dx[i]][b+dy[i]])
    36                 vis[a+dx[i]][b+dy[i]]=vis[a][b]+1,qx[++r]=a+dx[i],qy[r]=b+dy[i];
    37     }
    38     for(int i=t+1;i<=k;i++) dis[t][i]=dis[i][t]= vis[x[i]][y[i]]==0?inf:vis[x[i]][y[i]];
    39 }
    40 int main()
    41 {
    42     freopen("treasure.in","r",stdin);
    43     freopen("treasure.out","w",stdout);
    44     n=read(),m=read(),k=read(),T=read();int a=0;
    45     for(int i=1;i<=n;i++)
    46     {
    47         scanf("%s",mp[i]+1);
    48         for(int j=1;j<=m;j++)
    49             if(mp[i][j]=='*') x[a]=i,y[a++]=j;
    50             else if(mp[i][j]=='S') x[k]=i,y[k]=j;
    51     }
    52     for(int i=0;i<=k;i++) bfs(i);
    53     memset(dp,127,sizeof(dp));
    54     for(int i=0;i<k;i++) dp[1<<i][i]=0;
    55     for(int i=1;i<(1<<k);i++)
    56         for(int j=0;j<k;j++)
    57             if(!((1<<j)&i))
    58                 for(int o=0;o<k;o++)
    59                     if((1<<o)&i)
    60                     if(dis[o][j]!=inf)dp[i|(1<<j)][j]=min(dp[i|(1<<j)][j],dp[i][o]+dis[o][j]);
    61     for(int t,cnt,i=1;i<(1<<k);i++)
    62     {
    63         t=inf,cnt=0;
    64         for(int j=0;j<k;j++) if((1<<j)&i)
    65         if(dp[i][j]!=inf)t=min(t,dis[j][k]+dp[i][j]),cnt++;
    66         if(t<=T) ans=max(ans,cnt);
    67     }
    68     printf("%d",ans);
    69 }
    View Code

    T3 instrument

    题目大意:

    一个数列 划分成若干段使每段内无相同的数

    最短段的长度的最大值 以及满足这个条件的方案数

    思路:

    可以二分求出第一问的解 在判断可行的时候可以顺便求出第二问

    即用dp i表示最后一段以i为结尾的方案数 转移的时候可以从pre ~  i-x转移过来

    前缀和优化一下 判断最终dp值是否为0 即可check

    (但写法出现了一些偏差)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 530010
    13 #define MOD 998244353
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 //yyc score= 0
    23 int n,a[MAXN],b[MAXN],c[MAXN],pre[MAXN];
    24 ll ans,res,dp[MAXN],sum[MAXN];
    25 ll cheque(int x)
    26 {
    27     for(int i=1;i<=x;i++) dp[i]=sum[i]=0;
    28     for(int i=x;i<=n;i++)
    29     {
    30         if(i-pre[i]<x) {dp[i]=0,sum[i]=sum[i-1];continue;}
    31         if(!pre[i]) {dp[i]=sum[i-x]+1,sum[i]=sum[i-1]+dp[i];continue;}
    32         dp[i]=(sum[i-x]-(pre[i]==0?0:sum[pre[i]-1])+MOD)%MOD;
    33         if(dp[i]>2*MOD) dp[i]-=MOD;
    34         sum[i]=(sum[i-1]+dp[i])%MOD;
    35     }
    36     return dp[n]>0;
    37 }
    38 int main()
    39 {
    40     freopen("instrument.in","r",stdin);
    41     freopen("instrument.out","w",stdout);
    42     n=read();int l,r,mid;
    43     for(int i=1;i<=n;i++) a[i]=b[i]=read();
    44     sort(b+1,b+n+1);l=unique(b+1,b+n+1)-b-1;
    45     for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+l+1,a[i])-b;
    46     for(int i=1;i<=n;i++) pre[i]=c[a[i]],c[a[i]]=i,pre[i]=max(pre[i],pre[i-1]);
    47     l=1,r=n;
    48     while(l<=r)
    49     {
    50         mid=l+r>>1;
    51         if(cheque(mid)) ans=mid,res=dp[n],l=mid+1;
    52         else r=mid-1;
    53     }
    54     printf("%lld
    %lld",ans,res%MOD);
    55 }
    View Code
  • 相关阅读:
    泛型约束 where T : class,new()
    在Navicat for MySQL中打开视图时,提示视图没有主键的问题
    转:JQuery实现下拉框的数据加载和联动
    查询每门课程最高分的学生的学号,课程号,成绩
    转:SQL子句的执行顺序
    端口映射
    服务器与个人电脑的区别
    花生壳使用指南
    如何测试本机的公网IP能否被Internet用户访问
    利用ADSL拨号上网方式如何搭建服务器
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9872458.html
Copyright © 2011-2022 走看看