zoukankan      html  css  js  c++  java
  • 【60测试_联考2】【贪心】【模拟】【找规律_排序】

    第一题:

      给你N个字符串 ,你每次 可以 选择 其中 一个 字符串 的一段 前缀 进行 翻转 ,但 是你必须 保证 这个 前缀 的长度 是偶数 。你可以 进行 无限次 这样 的操作 ,并且如果两个字符串 变得 相同 的时候 ,你就可以把这两个字符串都删除掉,问最后最少剩下多少个字符串 ?n<=50, t( t 组数据)<=11

    解:  一直觉得这道题很神奇。写了好久的草稿,结果还是没看出来。其实根据偶数这个性质,只要再深入一点就可以发现了。无论如何翻转,原本相邻的 i 和 i+1 两个位置的字符是不会被拆开的,所以可以直接记录两个连着的字符。然后为了直观的判断,只需要以没两个字符的第一个字符为第一个关键字,第二个字符为第二个关键字将原字符串排序,排序后的状态肯定可以通过翻转得到,所以排完序后只要存在两个相同,那么这两个就符合条件。

      需要注意的是,只有两两之间才能删除,如果三个都可以,但是根据题意,在找到前两个后就被删了,因此不可能再匹配到第三个。

      赋初值,要清零。

      字符串(字母)的常用处理:转化为ASCII码记录。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define maxn 55
     6 using namespace std;
     7 struct pp{
     8     int one,two;
     9 };
    10 pp s[maxn][maxn];
    11 int n,t,num[maxn],ans;
    12 bool vis[maxn];
    13 const int comp(const pp&a,const pp&b)
    14 {
    15     if (a.one!=b.one) return a.one<b.one;
    16     return a.two<b.two;
    17 }
    18 void chuli(int cur)
    19 {
    20     char c[maxn];
    21     scanf("%s",c+1);
    22     int len=strlen(c+1);
    23     num[cur]=len;
    24     for (int i=1;i<=len/2;i++)
    25     {
    26         s[cur][i].one=min(c[i*2-1]-'a'+1,c[i*2]-'a'+1);
    27         s[cur][i].two=max(c[i*2-1]-'a'+1,c[i*2]-'a'+1);
    28     }
    29     if (len%2) {
    30         s[cur][len/2+1].one=c[len]-'a'+1;
    31         s[cur][len/2+1].two=0;
    32     }
    33     sort(s[cur]+1,s[cur]+len/2+1,comp);
    34 }
    35 void work()
    36 {
    37     ans=n;
    38     for (int i=1;i<=n;i++)
    39      for (int j=i+1;j<=n;j++)
    40        if (!vis[j]&&!vis[i]&&num[i]==num[j]){
    41               bool yes=false;
    42               int l=num[i];
    43               if (l%2) l=l/2+1;
    44               else l/=2;
    45               for (int k=1;k<=l;k++)
    46                 if (s[i][k].one!=s[j][k].one||s[i][k].two!=s[j][k].two){
    47                     yes=true;break;
    48                 } 
    49             if (yes) continue;
    50             vis[i]=true;vis[j]=true;    
    51             ans-=2;
    52        }
    53     printf("%d
    ",ans);
    54 }
    55 int main()
    56 {
    57     freopen("kahuucino.in","r",stdin);
    58     freopen("kahuucino.out","w",stdout);
    59     cin>>t;
    60     while(t)
    61     {
    62         memset(s,0,sizeof(s));
    63         memset(vis,0,sizeof(vis));//*****
    64         scanf("%d",&n);
    65         for (int i=1;i<=n;i++)
    66             chuli(i);
    67         work();
    68         t--;
    69     }
    70     return 0;
    71 }

    第二题:

      对于每只怪有两个值:战斗值和能力值。它们相互打,只有战斗值高X的打死战斗值低的Y,并且打死后的战斗值变为:自己原来的战斗值-Y的战斗值+Y的能力值。问战斗后,怪中战斗值+能力值最大能达到多少。(对于每一只怪,不一定要把剩下的怪打完,想打谁打谁)

    解:    这道题先开始根本没有读懂,以为必须把所有怪打完。。这道题用贪心做。把怪分为战斗型(负责打)和能力型(负责被打,因为打它获得正的战斗值)两种,然后将能力型按战斗值排序,战斗型按战斗值+能力值sum排序。对于某一个战斗值,可以恰好把能力型的所有怪打完(因为边打的时候战斗值会变大),这个战斗值为 “底线pos,在战斗型中第一个超过这个pos的怪即ans,因为战斗型按sum排序,而ans为战斗值+能力值,对于大于攻击值pos的所有战斗型怪能从能力值怪中获得的收益是相同的,所以只需比较这个sum,最靠前的即ans。当然,还有一种情况,就是用能力型中战斗值最大的一只打所有能力型怪,也可以获得很大的收益,将两者相比较得到ans。

      看来贪心还是不是很熟,排序很重要,怎么排,什么是最优解,满足什么条件,把这些都弄清楚,方法就出来了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define maxn 100005
     6 #define ll long long
     7 using namespace std;
     8 ll n,idi,idj,pos,s;
     9 struct pp{
    10     ll fight,val;
    11 };
    12 pp abled[maxn];
    13 struct oo{
    14     ll fight,sum;
    15 };
    16 oo attack[maxn];
    17 const ll comp1(const pp&a,const pp&b)
    18 {
    19     return a.fight<b.fight;
    20 }
    21 const ll comp2(const oo&a,const oo&b)
    22 {
    23     return a.sum>b.sum;
    24 }
    25 int main()
    26 {
    27     freopen("zyougamaya.in","r",stdin);
    28     freopen("zyougamaya.out","w",stdout);
    29     cin>>n;
    30     for (int i=1;i<=n;i++)
    31     {
    32         ll u,v;
    33         scanf("%I64d%I64d",&u,&v);
    34         if (v>u) {
    35             abled[++idi].fight=u;abled[idi].val=v-u;
    36         }
    37         else {
    38             attack[++idj].fight=u;attack[idj].sum=v+u;
    39         }
    40     }
    41     sort(abled+1,abled+1+idi,comp1);
    42     sort(attack+1,attack+1+idj,comp2);
    43     bool b=false;
    44     for (int i=1;i<=idi;i++)
    45     {
    46         if (!b&&s+abled[i].val>=abled[idi].fight){
    47             pos=abled[i].fight;    b=true;
    48         }
    49         s+=abled[i].val;//前缀和 
    50     }
    51     ll ans1=0,ans2=0;
    52     for (int i=1;i<=idj;i++)
    53     if (attack[i].fight>=pos){
    54         ans1=s+attack[i].sum;
    55         break;
    56     }
    57     ans2=s+abled[idi].fight*2;
    58     printf("%I64d",max(ans1,ans2));
    59     return 0;
    60 }

    第三题:

      有一个文件系统,支持7个操作:加入文件,加入文件夹,打开文件夹,删除文件,删除文件夹,回到上一个路径,输出当前路径的所有文件、文件夹。

    解:

      一看就是个模拟。乱搞就可以了。注意细节。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define maxn 105
      6 using namespace std;
      7 int q,cur=1,idx=1,p;
      8 int tot,he[maxn],ne[maxn],to[maxn];
      9 struct pp{
     10     int typ,fa;
     11     bool zai;
     12     char na[maxn*2];
     13 };
     14 pp s[maxn];
     15 void add(int a,int b,int t)
     16 {
     17     tot++;to[tot]=b;ne[tot]=he[a];he[a]=tot;
     18     s[b].fa=a;s[b].typ=t;s[b].zai=true;
     19 }
     20 void work1()//返回父路径 
     21 {
     22     if (s[cur].fa) cur=s[cur].fa;
     23     else printf("No parent directory!
    ");
     24 }
     25 void work2(char x[])//进入 文件夹 
     26 {
     27     int len=strlen(x+1);
     28     for (int i=he[cur];i;i=ne[i])
     29     if (s[to[i]].typ==2&&s[to[i]].zai){//wen jian jia
     30         int l=strlen(s[to[i]].na+1);
     31         if (l!=len) continue;
     32         bool yes=false;
     33         for (int j=1;j<=len;j++)
     34             if (s[to[i]].na[j]!=x[j]) {yes=true;
     35                 break;
     36             }
     37         if (yes) continue;
     38         cur=to[i];
     39         return ;
     40     }
     41     printf("No such directory!
    ");
     42 }
     43 void work3(char x[],int t)//找文件(夹),创文件(夹) 
     44 {
     45     int len=strlen(x+1);bool have=false;
     46     for (int i=he[cur];i;i=ne[i])
     47     if (s[to[i]].typ==t&&s[to[i]].zai){
     48         int l=strlen(s[to[i]].na+1);
     49         if (l!=len) continue;
     50         bool yes=false;
     51         for (int j=1;j<=len;j++)
     52             if (s[to[i]].na[j]!=x[j]) {yes=true;
     53                 break;
     54             }
     55         if (yes) continue;
     56         have=true;
     57         break;
     58     }
     59     if (!have) {
     60         ++idx;
     61         add(cur,idx,t);
     62         for (int i=1;i<=len;i++)
     63           s[idx].na[i]=x[i];
     64     }
     65     else{
     66         if (t==1) printf("File already exists!
    ");
     67         else printf("Directory already exists!
    ");
     68     } 
     69 }
     70 void work4(char x[],int t)//删除文件或文件夹 
     71 {
     72     int len=strlen(x+1);bool have=false;
     73     for (int i=he[cur];i;i=ne[i])
     74     if (s[to[i]].typ==t&&s[to[i]].zai){
     75         int l=strlen(s[to[i]].na+1);
     76         if (l!=len) continue;
     77         bool yes=false;
     78         for (int j=1;j<=len;j++)
     79             if (s[to[i]].na[j]!=x[j]) {yes=true;
     80                 break;
     81             }
     82         if (yes) continue;
     83         have=true;
     84         s[to[i]].zai=false;
     85         return ;
     86     }
     87     if(t==1) printf("No such file!
    ");
     88     else printf("No such directory!
    ");
     89 } 
     90 void print(int x)
     91 {
     92     if (!s[x].zai) return ;
     93     if (s[x].typ==1){
     94         printf("%s ",s[x].na+1);
     95         cout<<"<F>"<<endl;
     96     }
     97     else {
     98         printf("%s ",s[x].na+1);
     99         cout<<"<D>"<<endl;
    100     }
    101 }
    102 void work7(int pi)//ls 输出 递归 
    103 {
    104     int now=to[pi];
    105     if (ne[pi]==0) {
    106         print(now);
    107         return ;    
    108     }
    109     work7(ne[pi]);
    110     print(now);
    111 }
    112 int main()
    113 {
    114     freopen("nacumegu.in","r",stdin);
    115     freopen("nacumegu.out","w",stdout);
    116     cin>>q;
    117     while (q)
    118     {
    119         char op[10],name[maxn*2];
    120         scanf("%s",op);
    121         if (op[0]=='l'){
    122             p=he[cur];
    123             work7(p);
    124             q--;//***
    125             continue;//***
    126         }
    127         scanf("%s",name+1);
    128         if (op[0]=='c'){
    129             if (name[1]=='.') 
    130                 work1();
    131             else 
    132                 work2(name);
    133         }
    134         else if(op[0]=='t') work3(name,1);
    135         else if (op[0]=='r'){
    136             if (strlen(op)==2) 
    137                 work4(name,1);
    138             else 
    139                 work4(name,2);
    140         }
    141         else if (op[0]=='m') work3(name,2);
    142         q--;
    143     }
    144     return 0;
    145 }
  • 相关阅读:
    Jmeter测试报表相关参数说明
    jQuery实现图片延迟加载
    Jmeter 用动态参数进行测试
    MyEclipse 10.6 汉化和破解工具
    将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片
    List的二种循环速度比较
    java+flash在线拍照和编辑,保存到服务器(Spring3.2.2+swf+jquery)
    eclipse中如何去除警告:Class is a raw type. References to generic type Class<T> should be parameterized
    weblogic异常weblogic.utils.NestedRuntimeException: Cannot parse POST parameters of request
    在静态页面html中跳转传值
  • 原文地址:https://www.cnblogs.com/lx0319/p/6044616.html
Copyright © 2011-2022 走看看