hdu 4515:恶心的模拟题!代码有点丑陋!直接贴不解释!
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define M (31+28+24)
int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};
bool is_ok(int n)
{
if((n%4==0&&n%100!=0)||n%400==0)
return true;
return false;
}
int main()
{
int t,n;
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int q=n+M;
int now=2013;
int s=now,s1=0;
while(1)
{
if(is_ok(s))
{
if(q<=366)
break;
else
{
s++;
q-=366;
}
}
else
{
if(q<=365)
break;
else
{
s++;
q-=365;
}
}
}
int mo=0;
if(is_ok(s))
a[1]=29;
while(q>a[mo])
{
q-=a[mo];
mo++;
}
a[1]=28;
printf("%04d/%02d/%02d ",s,mo+1,q);
int g=now,p;
if(n<=M-1)
{
n=M-n;
int y,r;
if(n>31+28)
{
y=3;
r=n-31-28;
}
else if(n>31)
{
y=2;
r=n-31;
}
else
{
y=1;
r=n;
}
printf("2013/%02d/%02d\n",y,r);
}
else
{
p=n-M+1;
g=2012;
while(1)
{
if(is_ok(g))
{
if(p<=366)
break;
else
{
p-=366;
g--;
}
}
else
{
if(p<=365)
break;
else
{
p-=365;
g--;
}
}
}
if(is_ok(g))
{
a[1]=29;
}
mo=11;
while(p>a[mo])
{
p-=a[mo];
mo--;
}
a[1]=28;
printf("%04d/%02d/%02d\n",g,mo+1,a[mo]-p+1);
}
}
}
hdu 4517
用p[i][j]存放0~i-1 * 0~j-1里的黑点数目。
然后对枚举,
if(p[i+x-1][j+y-1]+p[i-1][j-1]-p[i+x-1][j-1]-p[i-1][j+y-1]==x*y)
ans++ ;
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,x,y;
char map[2001][2001];
int p[2001][2001];
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
else
{
memset(p,0,sizeof(map));
scanf("%d%d",&x,&y);
int i,j;
for(i=0;i<n;i++)
scanf("%s",map[i]);
if(map[0][0]=='*') p[0][0]=1;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
int a,b,c;
if(i-1>=0)
a=p[i-1][j];
else
a=0;
if(j-1>=0)
b=p[i][j-1];
else
b=0;
if(i-1>=0&&j-1>=0)
c=p[i-1][j-1];
else
c=0;
p[i][j]=a+b-c;
if(map[i][j]=='*')
p[i][j]++;
}
int ans=0;
int z=x*y;
for(i=0;i+x<=n;i++)
for(j=0;j+y<=m;j++)
{
int wo,ai,tm;
if(i<=0) wo=0;
else wo=p[i-1][j+y-1];
if(j<=0) ai=0;
else ai=p[i+x-1][j-1];
if(i<=0||j<=0) tm=0;
else tm=p[i-1][j-1];
if(p[i+x-1][j+y-1]+tm-wo-ai==z)
ans++;
}
if(x!=y)//如果x==y,横放竖放都一样
{
for(i=0;i+y<=n;i++)
for(j=0;j+x<=m;j++)
{
int wo,ai,tm;
if(i<=0) wo=0;
else wo=p[i-1][j+x-1];
if(j<=0) ai=0;
else ai=p[i+y-1][j-1];
if(i<=0||j<=0) tm=0;
else tm=p[i-1][j-1];
if(p[i+y-1][j+x-1]+tm-wo-ai==z)
ans++;
}
}
printf("%d\n",ans);
}
}
return 0;
}
不解释!
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int main()
{
int t,n,m,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&k,&m);
if(n<=m)
printf("%d\n",k);
else
{
if(n*k%m!=0)
printf("%d\n",n*k/m+1);
else
printf("%d\n",n*k/m);
}
}
}
hdu 4514
一开始,很SB的找欧拉回路,后来发现并没有要求所有景点都必须放入环中或者在最长路线中。
直接并查集,如果一条路的两端的父亲一样,那说明就有环。
如果没环,就输出并查集生成的树中,权值最大的。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int p[100010],ans[100010];
int find(int i)
{
if(i!=p[i]) return find(p[i]);
return i;
}
bool mege(int u,int v,int w)
{
int x=find(u);
int y=find(v);
if(x!=y)
{
p[x]=y;
ans[y]=ans[y]+ans[x]+w;
return false;
}
return true;
}
int n,m,u,v,w;
int main()
{
while(~scanf("%d%d",&n,&m))
{
int i;
bool ok=false;
for(i=1;i<=n;i++)
p[i]=i,ans[i]=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
if(!ok)
{
if(mege(u,v,w))
ok=true;
}
}
if(ok)
printf("YES\n");
else
{
int p=0;
for(i=1;i<=n;i++)
p=max(p,ans[i]);
printf("%d\n",p);
}
}
return 0;
}
hdu 4513:
如果没有要求递增或递减,那就是明显的最长回文串。O(n)的方法:
http://hi.baidu.com/chenwenwen0210/item/482c84396476f0e02f8ec230
所以只需在最长回文的基础上加个判断,但我老是在这判断上超时,后来是借鉴的这位的优化:
http://hi.baidu.com/chenwenwen0210/item/51b72039793833f56d15e9ba
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int s1[100010];
int s2[200020];
int p[200020],n;
void change()
{
s2[0]=-1;
s2[1]=0;
int i;
for(i=0;i<n;i++)
{
s2[i*2+2]=s1[i];
s2[i*2+3]=0;
}
n=n*2+2;
s2[n]=0;
}
void getp()
{
int i,id,mx=0;
for(i=n;s2[i]!=0;i++)
s2[i]=0;
for(i=1;i<n;i++)
{
if(mx>i)
p[i]=min(p[id*2-i],p[id]+id-i);
else
p[i]=1;
while(s2[i-p[i]]==s2[i+p[i]])
{
if(s2[i-p[i]]==0)
{
p[i]++;
}
else
{
int a=i-p[i];
int b=i+p[i];
if(a+2<=b-2&&s2[a]<=s2[a+2]&&s2[b]<=s2[b-2])
{
p[i]++;continue;
}
else if(a==b)
{
p[i]++;
continue;
}
else if(a+2>b-2)
{
p[i]++;
continue;
}
break;
}
}
if(p[i]+i>mx)
{
id=i;
mx=p[i]+i;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&s1[i]);
// printf("z\n");
change();
// printf("h\n");
getp();
// printf("j\n");
int ans=-1;
for(i=0;i<n;i++)
{
// printf("%d\n",p[i]);
ans=max(p[i],ans);
}
printf("%d\n",ans-1);
}
return 0;
}
这个就不解释了,一开始把时间弄成24小时了,WA了,都是不细心惹得错!
#include<stdio.h>
#define day (12*60*60)
int main()
{
int n,h,m,s,h1,m1,s1;
scanf("%d",&n);
while(n--)
{
scanf("%d:%d:%d",&h,&m,&s);
scanf("%d:%d:%d",&h1,&m1,&s1);
int now=(h*60+m)*60+s;
int past=(h1*60+m1)*60+s1;
past%=day;
if(now<past)
now=now+day-past;
else
now=now-past;
int ansh,ansm,anss;
ansh=now/3600;
now%=3600;
ansm=now/60;
now%=60;
anss=now;
printf("%02d:%02d:%02d\n",ansh,ansm,anss);
}
return 0;
}