problem 1001(hdu 4632)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4632

Palindrome subsequence

思路:记忆化DP,

dp[i][j]表示原字符串中[i,j]位置中出现的回文子序列的个数

递推关系:

dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]

如果str[i]==str[j]

dp[i][j]+=dp[i+1][j-1]

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=1010;
 6 const int mod=10007;
 7 int dp[maxn][maxn];
 8 char str[maxn];
 9 int dfs(int l,int r)
10 {
11     if(dp[l][r]!=-1)
12     return dp[l][r];
13     if(l==r)
14     {
15         dp[l][r]=1;
16         return dp[l][r];
17     }
18     if(l+1==r)
19     {
20         if(str[l]==str[r])
21         {
22             dp[l][r]=3;
23         }
24         else
25         dp[l][r]=2;
26         return dp[l][r];
27     }
28     int t=dfs(l+1,r-1);
29     dp[l][r]=0;
30     dp[l][r]+=dfs(l+1,r)+dfs(l,r-1)-t;
31     if(str[l]==str[r])
32     dp[l][r]+=t+1;
33     dp[l][r]%=mod;
34     if(dp[l][r]<0)//一开始没有考虑到
35     dp[l][r]+=mod;
36     return dp[l][r];
37 }
38 int main()
39 {
40     int T;
41     scanf("%d",&T);
42     int k=0;
43     while(T--)
44     {
45         getchar();
46         scanf("%s",str);
47         k++;
48         int len=strlen(str);
49         memset(dp,-1,sizeof(dp));
50         printf("Case %d: %d\n",k,dfs(0,len-1));
51     }
52     return 0;
53 }

View Code

problem 1004(hdu 4635)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4635

Strongly connected

思路:利用tarjan算法,将图分成多个强连通分量子图,查找出出度或入度为零并且子图点数最少的连通分量子图(假设称为最小子图),其点数为mmin

   将除最小子图的剩余部分连成完全有向图,把最小子图的点之间连成完全有向图,最后只用单向边连接两部分,减去原来的边数m即可;

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<stack>
  7 using namespace std;
  8 const int maxn=100010;
  9 struct node
 10 {
 11     int u;
 12     int v;
 13     int next;
 14 }edge[maxn];
 15 int head[maxn];
 16 int in[maxn],out[maxn];
 17 int dfn[maxn];
 18 int low[maxn];
 19 int sccno[maxn];
 20 int num[maxn];
 21 int cn,deep,sccnum;
 22 stack<int>st;
 23 void init()
 24 {
 25     memset(head,-1,sizeof(head));
 26     memset(dfn,0,sizeof(dfn));
 27     memset(sccno,0,sizeof(sccno));
 28     memset(in,0,sizeof(in));
 29     memset(out,0,sizeof(out));
 30     memset(num,0,sizeof(num));
 31     deep=0;
 32     sccnum=0;
 33     cn=0;
 34     while(!st.empty())
 35     {
 36         st.pop();
 37     }
 38 }
 39 void add(int u,int v)
 40 {
 41     edge[cn].u=u;
 42     edge[cn].v=v;
 43     edge[cn].next=head[u];
 44     head[u]=cn++;
 45 }
 46 void tarjan(int u)
 47 {
 48     st.push(u);
 49     low[u]=dfn[u]=++deep;
 50     int i;
 51     for(i=head[u];i!=-1;i=edge[i].next)
 52     {
 53         int v=edge[i].v;
 54         if(!dfn[v])
 55         {
 56             tarjan(v);
 57             low[u]=min(low[u],low[v]);
 58         }
 59         else if(!sccno[v])
 60         {
 61             low[u]=min(low[u],dfn[v]);
 62         }
 63     }
 64     if(low[u]==dfn[u])
 65     {
 66         sccnum++;
 67         while(1)
 68         {
 69             int x=st.top();
 70             st.pop();
 71             sccno[x]=sccnum;
 72             if(x==u)
 73             break;
 74         }
 75     }
 76 }
 77 int main()
 78 {
 79     int T;
 80     scanf("%d",&T);
 81     int k=0;
 82     while(T--)
 83     {
 84         __int64 m,n;
 85         scanf("%I64d%I64d",&n,&m);
 86         k++;
 87
 88         int i,j;
 89
 90         init();
 91         for(i=0;i<m;i++)
 92         {
 93             int u,v;
 94             scanf("%d%d",&u,&v);
 95             add(u,v);
 96         }
 97         for(i=1;i<=n;i++)
 98         {
 99             if(!dfn[i])
100             {
101                tarjan(i);
102             }
103         }
104         //printf("scc=%d",sccnum);
105         if(sccnum==1)
106         {
107             printf("Case %d: -1\n",k);
108             continue;
109         }
110         for(i=1;i<=n;i++)
111         {
112             num[sccno[i]]++;
113             for(j=head[i];j!=-1;j=edge[j].next)
114             {
115                 int v=edge[j].v;
116                 if(sccno[i]!=sccno[v])
117                 {
118                     out[sccno[i]]++;
119                     in[sccno[v]]++;
120                 }
121             }
122         }
123         __int64 mmin=1e13;
124         for(i=1;i<=sccnum;i++)
125         {
126             if(in[i]==0||out[i]==0)
127             {
128                 if(mmin>num[i])
129                 mmin=num[i];
130             }
131         }
132         __int64 res=0;
133         res+=(n-mmin)*(n-mmin-1);
134         res+=mmin*(mmin-1);
135         res+=(n-mmin)*mmin;
136         res-=m;
137         printf("Case %d: %I64d\n",k,res);
138     }
139 }

View Code

problem 1007(hdu 4638)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4638

思路:(官方题解)

题意为询问一段区间里的数能组成多少段连续的数。先考虑从左往右一个数一个数添加,考虑当前添加了i - 1个数的答案是x,那么添加完i个数后的答案是多少?可以看出,是根据a[i]-1和a[i]+1是否已经添加而定的,如果a[i]-1或者a[i]+1已经添加一个,则段数不变,如果都没添加则段数加1,如果都添加了则段数减1。设v[i]为加入第i个数后的改变量,那么加到第x数时的段数就是sum{v[i]} (1<=i<=x}。仔细想想,若删除某个数,那么这个数两端的数的改变量也会跟着改变,这样一段区间的数构成的段数就还是他们的v值的和。将询问离线处理,按左端点排序后扫描一遍,左边删除,右边插入,查询就是求区间和。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn=100010;
  7 int data[maxn];
  8 int pos[maxn];
  9 int in[maxn];
 10 int tree[maxn];
 11 int ss[maxn];
 12 int res[maxn];
 13 int n,m;
 14 struct node
 15 {
 16     int l;
 17     int r;
 18     int xh;
 19 } que[maxn];
 20 bool cmp(struct node a,struct node b)
 21 {
 22     if(a.l==b.l)
 23         return a.r<b.r;
 24     else
 25         return a.l<b.l;
 26 }
 27 int lowbit(int x)
 28 {
 29     return x&(-x);
 30 }
 31 void update(int s,int num)
 32 {
 33     while(s<=n)
 34     {
 35         tree[s]+=num;
 36         s+=lowbit(s);
 37     }
 38 }
 39 int query(int s)
 40 {
 41     int sum=0;
 42     while(s>0)
 43     {
 44         sum+=tree[s];
 45         s-=lowbit(s);
 46     }
 47     return sum;
 48 }
 49 int main()
 50 {
 51     int T;
 52     scanf("%d",&T);
 53     while(T--)
 54     {
 55         memset(tree,0,sizeof(tree));
 56         memset(pos,0,sizeof(pos));
 57         scanf("%d%d",&n,&m);
 58         int i;
 59         for(i=1; i<=n; i++)
 60         {
 61             scanf("%d",&data[i]);
 62             pos[data[i]]=i;
 63         }
 64         int l,r;
 65         for(i=0; i<m; i++)
 66         {
 67             scanf("%d%d",&l,&r);
 68             que[i].l=l;
 69             que[i].r=r;
 70             que[i].xh=i;
 71         }
 72         sort(que,que+m,cmp);
 73         memset(in,0,sizeof(in));
 74         memset(ss,0,sizeof(ss));
 75         for(i=1; i<=n; i++)
 76         {
 77             if(in[data[i]-1])ss[i]++;
 78             if(in[data[i]+1])ss[i]++;
 79             if(ss[i]==0)
 80                 update(i,1);
 81             if(ss[i]==2)
 82                 update(i,-1);
 83             in[data[i]]=1;
 84         }
 85         l=1;
 86         for(i=0; i<m; i++)
 87         {
 88             for(; l<que[i].l; l++)
 89             {
 90                 if(data[l]>1&&pos[data[l]-1]>l)
 91                 {
 92                     update(pos[data[l]-1],1);
 93                 }
 94                 if(data[l]<n&&pos[data[l]+1]>l)
 95                 {
 96                     update(pos[data[l]+1],1);
 97                 }
 98             }
 99             res[que[i].xh]=query(que[i].r)-query(que[i].l-1);
100         }
101         for(i=0; i<m; i++)
102         {
103             printf("%d\n",res[i]);
104         }
105     }
106     return 0;
107 }

View Code

problem 1008(hdu 4639)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4639

Hehe

思路:hehe个数是1,hehehe的个数是2,hehehehe的个数是3。那么表示的意思的种数分别是2,3,5可以推出斐波纳挈数列

将字符串里的统计连续hehe的数量,,再相乘即可

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=10100;
 6 const int mod=10007;
 7 char str[maxn];
 8 int st[maxn];
 9 void init()
10 {
11     int i;
12     st[0]=0;
13     st[1]=2;
14     st[2]=3;
15     for(i=3;i<=10090;i++)
16     {
17         st[i]=(st[i-2]+st[i-1])%mod;
18     }
19 }
20 int run()
21 {
22     int len=strlen(str);
23     int i;
24     int num=0;
25     int sum=1;
26     for(i=0;i<len-3;)
27     {
28         if(str[i]=='h'&&str[i+1]=='e'&&str[i+2]=='h'&&str[i+3]=='e')
29         {
30             num++;
31             i+=2;
32         }
33         else
34         {
35             if(num!=0)
36             sum=sum*st[num]%mod;
37             num=0;
38             i++;
39         }
40     }
41     if(num!=0)
42     sum=sum*st[num]%mod;
43     return sum;
44 }
45 int main()
46 {
47     int T,k=0;
48     scanf("%d",&T);
49     init();
50     while(T--)
51     {
52         getchar();
53         scanf("%s",str);
54         k++;
55         printf("Case %d: %d\n",k,run());
56     }
57     return 0;
58 }

View Code

problem 1011(hdu 4642)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4642

Fliping game

思路:只需要判断map[m][n]是0还是1即可,0则Bob胜,否则Alice胜

因为不管翻动哪一个盒子,总会反动到右下角的那个,当右下角是1时,需翻动奇数次盒子才能翻成0,当右下角是0时,需翻动偶数次盒子才能翻成0

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int main()
 6 {
 7     int T;
 8     scanf("%d",&T);
 9     while(T--)
10     {
11         int n,m;
12         scanf("%d%d",&n,&m);
13         int a;
14         for(int i=0;i<n;i++)
15         {
16             for(int j=0;j<m;j++)
17             {
18                 scanf("%d",&a);
19             }
20         }
21         if(a==1)
22         printf("Alice\n");
23         else
24         printf("Bob\n");
25     }
26     return 0;
27 }

View Code

转载于:https://www.cnblogs.com/wanglin2011/p/3233230.html

2013 Multi-University Training Contest 4 部分解题报告相关推荐

  1. 2013 Multi-University Training Contest 5 部分解题报告

    problem 1005(hdu 4647) 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4647 Another Graph Game 思路:(官方题解 ...

  2. 2013 Multi-University Training Contest 6 部分解题报告

    problem 1001(hdu 4655) 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4655 1 #include<stdio.h> 2 ...

  3. 2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 Apare_xzc

    2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 by xzc,zx,lj 先 ...

  4. 2012 winter training @HIT Day 2 解题报告

    今天第二天,主要练习二分和枚举.其实我突然发现,当做题突然卡主的时候,不妨想想今天练习的是什么内容-- 传送门http://acm.hit.edu.cn/hoj/contest/view?id=100 ...

  5. LeetCode第187场周赛(Weekly Contest 187)解题报告

    差点又要掉分了,还好最后几分钟的时候,绝杀 AK.干巴爹!!! 第一题:思路 + 模拟暴力. 第二题:线性扫描. 第三题:双指针(滑动窗口) + 优先队列. 第四题:暴力每一行最小 k 个 + 优先队 ...

  6. LeetCode第176场周赛(Weekly Contest 176)解题报告

    又是一周掉分之旅,我发现,LeetCode周赛的数据好水,所以有的时候,实在没思路,先暴力解决试试(即使分析出时间复杂度会超时),比如第二题和第三题都可以暴力通过,GG思密达. 这周主要使用了数据结构 ...

  7. CQUPT WEEKLY TRAINING (3)解题报告

    T1: 一些士兵围成圈,每个士兵有个高度.求一个最小的相离高度差. 循环维护一遍,然后判断一下头尾. #include <cstdio> #include <algorithm> ...

  8. 2018 Multi-University Training Contest 3 Problem F. Grab The Tree 【YY+BFS】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6324 Problem F. Grab The Tree Time Limit: 2000/1000 MS ...

  9. 2018 Multi-University Training Contest 4 Problem E. Matrix from Arrays 【打表+二维前缀和】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6336 Problem E. Matrix from Arrays Time Limit: 4000/20 ...

最新文章

  1. Linux绝对路径和相对路径简单介绍
  2. 操作系统实验1—实现单处理机下的进程调度程序
  3. 理解几个网络硬件(调制解调器、路由器、交换机)的基本作用
  4. 你真的了解用户吗?-浅谈《用户画像》的意义和方法
  5. 计算机算法在生物信息学中的应用,计算机算法在生物信息学中的应用综述.doc...
  6. 2021高考理综各科成绩查询,2021理综分数怎么分配 各科目是多少分
  7. QQ恶搞 - 让艾特你的人语无伦次
  8. 计算机学院考勤管理办法,计算机学院软件学院考勤制度(试行).doc
  9. 多曝光HDR成像 跑出来的图片颜色变绿
  10. mis服务器系统,MIS系统中服务器推技术的实现
  11. 第四章计划:制定项目使命、愿景、目的和目标
  12. 华东师范大学、普陀区科委领导一行莅临和数集团
  13. 利用Python实现自动识别图片文字 -- OCR
  14. 手把手教你做Android聊天机器人
  15. PTA天梯赛L1-040 最佳情侣身高差(c语言实现)
  16. 一点点linux系统的学习心得
  17. 通过IP查询计算机名
  18. 【工具推荐】最简单方法创建 README
  19. 12 【网页布局总结 元素的显示与隐藏】
  20. 数字图像处理-图像形态学处理-颗粒提取

热门文章

  1. 20190905:(leetcode习题)爬楼梯
  2. linux测试dvi接口,TeX Live DVI字体数据解析整数溢出漏洞
  3. python函数主要通过接口与外界通信_PySpark源码解析,用Python调用高效Scala接口,搞定大规模数据分析...
  4. VB APP对象属性一览表 + 灵活使用VB的APP对象
  5. 英语总结系列(二十四):历经GCT的一月
  6. 高通把苹果逼急了?传苹果正大力研发调制解调器
  7. 大连理工大学在CVPR18大规模精细粒度物种识别竞赛中获得冠军
  8. 机器人能力再进化,组装宜家椅子只需20分钟! | Science Robotics论文
  9. 一样的打游戏,不一样的酷
  10. 这位顶会领域主席的论文被自己的AI审稿系统拒绝了