A - Minimum’s Revenge HDU - 5922
题意:有n个节点,编号为1~n,任意两个点之间的权值为两点编号的最小公倍数,问建最小生成树的最少花费为多少。
题解:最少花费即所有节点都与1号节点连边。
答案为n*(n+1)/2-1
C - Mr. Frog’s Problem HDU - 5924
题意:给出两个数A和B,让你找出C和D满足A/B+B/A<=C/D+D/C,问C、D数对的个数。
题解:满足条件的只有A、B本身。
E - Mr. Frog’s Game HDU - 5926
题意:根据连连看的规则,把两个一样的数字,用三根以下的线连起来(即路线最多变换两次),问能否消除至少一对数字。
题解:
#include<iostream>
#include<cstdio>
using namespace std;
int a[105][105];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int main()
{
int t;
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
bool flag=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int z=0;z<4;z++)
{
int mx=i+dx[z],my=j+dy[z];
if(mx>=1&&mx<=n&&my>=1&&my<=m)
{
if(a[mx][my]==a[i][j])
{
flag=1;
break;
}
}
}
if(i==1||i==n)
{
for(int z=1;z<=m;z++)
{
if(j!=z)
{
if(a[i][j]==a[i][z])
{
flag=1;
break;
}
}
}
}
if(j==1||j==m)
{
for(int z=1;z<=n;z++)
{
if(i!=z)
{
if(a[i][j]==a[z][j])
{
flag=1;
break;
}
}
}
}
}
}
printf("Case #%d: ",k);
if(flag)
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
}
H - Basic Data Structure HDU - 5929
题意:给你一个栈,支持4种操作。PUSH:将1或0插入队列、POP:将栈顶元素弹出、REVERSE:将栈顶和栈底翻转(把栈倒过来)、QUERY:从栈顶到栈底元素的nand值。(nand:1 nand 1 = 0,1 nand 0 =1, 0 nand 1=1,0 nand 0 =1)。
题解:用双端队列模拟,主要记录离栈顶和栈底 最近和最远的0的位置。
真的难==
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
deque<int>q;
int a[400000+10];
char s[10];
int n;
int main()
{
int t;
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
printf("Case #%d:\n",k);
scanf("%d",&n);
bool flag=1;
while(!q.empty())
{
q.pop_front();
}
int l=n,r=n-1;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
if(s[2]=='S')
{
int num;
cin>>num;
if(flag)
{
a[++r]=num;
if(num==0)
q.push_back(r);
}
else
{
a[--l]=num;
if(num==0)
q.push_front(l);
}
}
if(s[2]=='P')
{
if(flag)
{
if(a[r]==0) q.pop_back();
r--;
}
else
{
if(a[l]==0) q.pop_front();
l++;
}
}
if(s[2]=='V')
{
flag^=1;
}
if(s[2]=='E')
{
if(q.empty())
{
if(l>r)
{
printf("Invalid.\n");
}
else
{
int sum=r-l+1;
if(sum%2==1)
{
printf("1\n");
}
else
{
printf("0\n");
}
}
}
else
{
if(flag)
{
int sum=q.front()-l;
if(sum%2==1)
{
if(q.front()==r) printf("1\n");
else printf("0\n");
}
else
{
if(q.front()==r) printf("0\n");
else printf("1\n");
}
}
else
{
int sum=r-q.back();
if(sum%2==1)
{
if(q.back()==l) printf("1\n");
else printf("0\n");
}
else
{
if(q.back()==l) printf("0\n");
else printf("1\n");
}
}
}
}
}
}
return 0;
}
J - Mission Possible HDU - 5931
题意:有一段长D米的路,走在路上每秒掉A点血,你现在可以花费G1提高1点血上限,花费G2提高1点速度(速度不能超过D),花费G3提高每秒回复能力(先掉血再回复),如果你的血掉到0以下则不能通过,问最少花费多少才能通过这段路。
题解:有两种策略通过这段路。①不回复,只靠血上限硬抗。②先加一下血,再通过回复与掉血持平过去。
我们枚举速度,再比较两种方案的花费,求最小值即可。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
for(int k=1;k<=T;k++)
{
long long D,A,G1,G2,G3;
scanf("%lld%lld%lld%lld%lld",&D,&A,&G1,&G2,&G3);
long long ans=1e15+7;
for(int v=1;v<=D;v++)
{
long long sum=min((long long)ceil(1.0*D/v*A)*G1,A*G1+A*G3);//向上取整
ans=min(ans,v*G2+sum);
}
printf("Case #%d: %lld\n",k,ans);
}
return 0;
}