这次的比赛。。被虐爆了。。做了一个多小时确定下来除了第一题我都做不出来之后。。。我就。。。就。。。。。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4510
题解:水题,格式要注意,还需要注意的是时钟。。。一圈12小时。。不是24小时。。。
#include
using namespace std;
int main()
{
int n;
scanf("%d", &n);
while (n--)
{
int a, b, c, d, e, f;
scanf("%d:%d:%d %d:%d:%d", &a, &b, &c, &d, &e, &f);
int xt = a * 3600 + b * 60 + c;
int yt = d * 3600 + e * 60 + f;
a %= 12; d%= 12;
int xtime = a * 3600 + b * 60 + c;
int ytime = d * 3600 + e * 60 + f;
while (xtime < ytime) xtime += 43200;
int cha = xtime - ytime;
printf("%02d:%02d:%02d\n", cha/3600, (cha%3600)/60, (cha%3600)%60);
}
return 0;
}
连接:http://acm.hdu.edu.cn/showproblem.php?pid=4511
题解:谁会啊。。最后了全场也就5个AC的有木有!!!
一下转自大牛(http://hi.baidu.com/chenwenwen0210/item/ca0768d039b0f1d793a974c9)
解题报告:这题初看没什么头续,看到了这些路径,然后又想看的数据范围,K很好,想到了Trie,然后又想到了字符串匹配,于是想到了AC自动机。
想到了AC自动机,这题就好做了,就是一个AC自动机DP嘛。
把题目给的非法路径构成一棵Trie树,然做跑一次AC自动机。
然后做DP
dp[i][j]代表在第i个点自动机状态在j的最小距离。
然后枚举可走的点去转移就行了。
自动机状态最多有5*100个。
总的DP状态有50*500,每一个转移是50,最后的复杂度是50*50*500
刚刚过题目。
PS:一次AC,很高兴。
#include
#include
#include
const int MAX=1005;
const int MAXSON=50;
struct
{
int id,next[MAXSON],fail;
}node[1000000];
int n,tot;
char mod[1000005];
int len[MAX];
int q[1000000];
void clr()
{
int i;
tot++;
for(i=0;i0)//自动机添加一个往前走的东西。错在这里啊,好久没有用AC自动机了
node[tmp].id=1;
for(i=0;i0)
{
puts("Can not be reached!");
continue;
}
dp[1][h]=0;
double cost=0;
for(i=1;i<=n;i++)
{
for(j=0;j<=tot;j++)
{
if(dblcmp(dp[i][j]-INF)==0)continue;
for(k=i+1;k<=n;k++)
{
h=node[j].next[k-1];
if(node[h].id)continue;
cost=disPP(p[i],p[k])+dp[i][j];
if(cost
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4512
题解:(转自大牛http://www.cnblogs.com/fzf123/archive/2013/03/23/2976903.html)
做法:枚举断点,分成两个段,求最长公共上升子序列。
/*
Author:Zhaofa Fang
Lang:C++
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4513
题解:(转自:http://hi.baidu.com/chenwenwen0210/item/51b72039793833f56d15e9ba)
解题报告:这题其实是求一个最长的回文子串,这儿和以前不一样的是要求是先上升后下降。
我们可以通过Manacher算法改造过来
下面是学习资料。
http://hi.baidu.com/chenwenwen0210/item/482c84396476f0e02f8ec230
和普通回文串不一样的地方就是每一扩展的时候要判断一下是不是<=前面的值。
具体改造见代码。
#include
#include
#include
#include
另一位大牛的:
http://www.cnblogs.com/aigoruan/archive/2013/03/22/2976538.html
代码就不贴了。。。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514
题解:好久没做图论了。。这次看到傻眼了。。。于是当时就没做。。第二天起床之后发现原来没那么难。。。。简单一个并查集就行了。。我狂晕。。。最好一次机会让我给错过了。。以后比赛坚决不能放弃了。。。。。
#include
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
const int maxn = 1000005;
int fa[maxn], len[maxn];
int n, m;
int find(int x)
{
if (x == fa[x]) return x;
return find(fa[x]);
}
int main()
{
while (scanf("%d %d", &n, &m) != EOF)
{
int i;
bool flag = false;
for (i=0; i <= n; i++) fa[i] = i;
memset(len, 0, (n+1)*sizeof(len[0]));
for (i=0; i maxlen)
maxlen = len[i];
printf("%d\n", maxlen);
}
}
return 0;
}