比赛链接
http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=8572
今天又全跪了,0题,我想哭,不过比赛就是这样,生活还得继续,不能放弃,真的,没关系,好好总结,以后多做总结,多看看以前做的题,温故而知新,
手脑要配合一起思考,每天总结当天的收获,哪里不足要加以改进,严格对待自己的缺点,每天与自己比,不要和别人比,每个人的情况都不相同,每天要赢自己一把,
注意休息,注意身体。
这次比赛有两道题我做过,
1008题即HDU3833题 这题做过,已经记不清这题是自己做的还是在网上搜的了。
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=3833
这次我开始是想用hash来遍历的,不过遍历要三重循环,但是当时没看到 the latter is a permutation of 1 to N.认为ai可能很大,就放弃hash了
那时觉得二分比较好(n*nlog(n))的复杂度,不过也超时,
正确的方法是用hash记录每个数的位置,hash【a【i】】=i 因为a【i】是1到n的数n<=10000;
再看hash【】是否在i j 范围内。
二分超时代码,此刻,我觉得这代码不止n*n*log(n)了,它还有个排序,我太天真了。加个排序还不如一个for直接找。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[10010],b[10010];
int two(int i,int j,int n)
{
int l,r,mid;
l=i; r=j;
while(l<=r)
{
mid=(l+r)/2;
if(n<b[mid])
{
r=mid-1;
}
else if(n>b[mid])
{
l=mid+1;
}
else
{
return 1;
}
}
return 0;
}
int main(void)
{
int i,j,k,n,t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int success=0;
for(i=0;i<n;i++)
{
scanf("%d",a+i);
b[i]=a[i];
}
for(i=0;i<n;i++)
{
for(j=i+2;j<n;j++)
{
k=a[i]+a[j];
if(k%2==0)
{
sort(b+i,b+j);
if(two(i,j,k/2))
{
printf("Y
");
success=1;
break;
}
}
}
if(success)
break;
}
if(success==0)
printf("N
");
}
return 0;
}
hash代码
#include<stdio.h>
#include<string.h>
int main(void)
{
int i,j,k,n,t;
int a[10005],hash[10005];
scanf("%d",&t);
while(t--)
{
int success=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",a+i);
hash[a[i]]=i;
}
for(i=0;i<n;i++)
{
for(j=i+2;j<n;j++)
{
if((a[i]+a[j])%2==0)
{
k=(a[i]+a[j])/2;
if(i<hash[k]&&hash[k]<j)
{
printf("Y
");
success=1;
break;
}
}
}
if(success)
break;
}
if(success==0)
printf("N
");
}
return 0;
}
1001题即HDU2054题
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=2054
这题以前搞过,觉得该想的数据多想了,一直没过,就放弃了。没想又碰到了。 花了将近3个小时终于AC了
这题好痛苦啊,开始超时,还有很多细节没处理WA,到最后竟然数组开小了,开成100000才AC
对于这题有三个注意点
负号处理
前导0
后面无效0
我把它们全部多处理掉。
开始代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
char a[100000],b[100000];
char s1[100000],s2[100000];
int main(void)
{
int i,j,k;
int flag1,flag2,k1,k2,k3,k4;
while(scanf("%s%s",a,b)==2)
{
memset(s1,' ',sizeof(s1));
memset(s2,' ',sizeof(s2));
k1=strlen(a); k2=strlen(b);
k3=0; k4=0; flag1=0; flag2=0;
int h1=0,h2=0;
int f1=0,f2=0;
if(a[0]=='-')
f1=1;
if(b[0]=='-')
f2=1;
for(i=0;i<k1||i<k2;i++)
{
if((a[i]!='0'&&a[i]!='-')||h1)
{
h1=1;
s1[k3++]=a[i];
if(a[i]=='.')
flag1=1;
}
if((b[i]!='0'&&b[i]!='-')||h2)
{
h2=1;
s2[k4++]=b[i];
if(b[i]=='.')
flag2=1;
}
}
s1[k3]=' '; s2[k4]=' ';
if(flag1&&flag2)
{
k=max(k3,k4);
for(i=k-1;i>=0;i--)
{
if(flag1&&s1[i]=='0')
{
s1[i]=' ';
}
else if(flag1&&s1[i]=='.')
{
s1[i]=' ';
flag1=0;
}
else if(flag1&&s1[i]==' ')
{
s1[i]=' ';
}
else
{
flag1=0;
}
if(flag2&&s2[i]=='0')
{
s2[i]=' ';
}
else if(flag2&&s2[i]=='.')
{
s2[i]=' ';
flag2=0;
}
else if(flag2,s2[i]==' ')
{
s2[i]=' ';
}
else
{
flag2=0;
}
if(flag1==0&&flag2==0)
break;
}
}
else if(flag1)
{
for(i=k3-1;i>=0;i--)
{
if(flag1&&s1[i]=='0')
{
s1[i]=' ';
}
else if(flag1&&s1[i]=='.')
{
s1[i]=' ';
flag1=0;
}
else
break;
}
}
else if(flag2)
{
for(i=k4-1;i>=0;i--)
{
if(flag2&&s2[i]=='0')
{
s2[i]=' ';
}
else if(flag2&&s2[i]=='.')
{
s2[i]=' ';
flag2=0;
}
else
break;
}
}
//printf("%s %s
",s1,s2);
if(f1==f2)
{
if(strcmp(s1,s2)==0)
printf("YES
");
else
printf("NO
");
}
else
{
if(strlen(s1)==0&&strlen(s2)==0)
printf("YES
");
else
printf("NO
");
}
}
return 0;
}
后来想想没有必要要s1和s2数组,因为新的处理前导0和‘-’后的字符串,一定延后于前面的数组。
看代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
char a[100000],b[100000];
//char s1[100000],s2[100000];
int main(void)
{
int i,j,k;
int flag1,flag2,k1,k2,k3,k4;
while(scanf("%s%s",a,b)==2)
{
//memset(s1,' ',sizeof(s1));
//memset(s2,' ',sizeof(s2));
k1=strlen(a); k2=strlen(b);
k3=0; k4=0; flag1=0; flag2=0;
int h1=0,h2=0;
int f1=0,f2=0;
if(a[0]=='-')
f1=1;
if(b[0]=='-')
f2=1;
for(i=0;i<k1||i<k2;i++)
{
if((a[i]!='0'&&a[i]!='-')||h1)
{
h1=1;
a[k3++]=a[i];
if(a[i]=='.')
flag1=1;
}
if((b[i]!='0'&&b[i]!='-')||h2)
{
h2=1;
b[k4++]=b[i];
if(b[i]=='.')
flag2=1;
}
}
a[k3]=' '; b[k4]=' ';
if(flag1&&flag2)
{
k=max(k3,k4);
for(i=k-1;i>=0;i--)
{
if(flag1&&a[i]=='0')
{
a[i]=' ';
}
else if(flag1&&a[i]=='.')
{
a[i]=' ';
flag1=0;
}
else if(flag1&&a[i]==' ')
{
a[i]=' ';
}
else
{
flag1=0;
}
if(flag2&&b[i]=='0')
{
b[i]=' ';
}
else if(flag2&&b[i]=='.')
{
b[i]=' ';
flag2=0;
}
else if(flag2,b[i]==' ')
{
b[i]=' ';
}
else
{
flag2=0;
}
if(flag1==0&&flag2==0)
break;
}
}
else if(flag1)
{
for(i=k3-1;i>=0;i--)
{
if(flag1&&a[i]=='0')
{
a[i]=' ';
}
else if(flag1&&a[i]=='.')
{
a[i]=' ';
flag1=0;
}
else
break;
}
}
else if(flag2)
{
for(i=k4-1;i>=0;i--)
{
if(flag2&&b[i]=='0')
{
b[i]=' ';
}
else if(flag2&&b[i]=='.')
{
b[i]=' ';
flag2=0;
}
else
break;
}
}
//printf("%s %s
",s1,s2);
if(f1==f2)
{
if(strcmp(a,b)==0)
printf("YES
");
else
printf("NO
");
}
else
{
if(strlen(a)==0&&strlen(b)==0)
printf("YES
");
else
printf("NO
");
}
}
return 0;
}
网上看了一些代码,有些没有处理负数即 -0和0,-0010 -10,也AC了,不过他处理前导0后缀无效0的方法比较好。
看代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char a[100024],b[100024],c[100024],d[100024];//万恶的数组,刚开始因为开小了,结果一直wa,都找不到原因
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
while(scanf("%s%s",a,b)!=EOF)
{
int j=0;
while(a[j]=='0')
{
j++;
}
int k=j;
while(a[j])
{
c[j-k]=a[j];
j++;
}
j=0;//对a数组删除前面输入的零,e.g00001==1
while(b[j]=='0')
{
j++;
}
k=j;
while(b[j])
{
d[j-k]=b[j];
j++;
}//对b数组删除前面输入的零
j=0;
if(strchr(c,'.'))//字符串判断函数,如果c字符串中含有'.'则返回'.'的位置指针,否则返回NULL
{
while(c[j])
{
j++;
}
j--;
while(c[j]=='0')
{
c[j]=' ';
j--;
}//删除小数点后面的零,e.g 123.000=123.00000000
if(c[j]=='.')
c[j]=' ';//删除小数点,e.g 123.0000=123
}
j=0;
if(strchr(d,'.'))
{
while(d[j])
{
j++;
}
j--;
while(d[j]=='0')
{
d[j]=' ';
j--;
}
if(d[j]=='.')
d[j]=' ';
}//类似以上处理
/*if(strlen(c)!=strlen(d))
printf("NO
");//判断长度是否相等
else//比较
{
int i=0,t=0;
while(c[i])
{
if(c[i]!=d[i])
{
t++;
break;
}
i++;
}
if(t==0)
{
printf("YES
");
}
else
{
printf("NO
");
}
}*/
if(strcmp(c,d)==0)
printf("YES
");
else
printf("NO
");
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
}
//system("pause");
return 0;
}
这题的数据应该是按常识来的例如是不会出现-0 0 -0010 10 这样的数据的。也不会出现0010 10这样的数据
又看了只处理小数点后面无效的0的也过了。
看代码
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
char a[100000],b[100000];
void change(char s[])
{
int i,len;
len = strlen(s);
if(strstr(s,"."))
{
for(i = len-1; s[i] == '0'; i--)
{
s[i] = ' ';
len--;
}
}
if(s[len-1] == '.')
s[len-1] = ' ';
}
int main()
{
while(scanf("%s%s",a,b)!=EOF)
{
change(a);
change(b);
if(strcmp(a,b))
printf("NO
");
else
printf("YES
");
}
return 0;
}
对于这题只要处理小数点后面的无效的0。就可以了。
1002题对应HDU1396题
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1396
这个是我第一个开始做的,看到它的时候,觉得它明显不难,因为只是数个三角形而已,所以就第一个做它,当时太急了,想了一下就开始做了
根本没有考虑这样做是否正确,还有没有其他的想法,导致错了盲目改,改了又发现又有地方没有考虑到,做题要做到稳中求快,别一味求快,这样搞不好浪费的时间更多。
这题浪费了我很多时间,导致做其他题目没有时间,更加紧张,
比完后去吃饭的路上,我又想了想这题,想到我是不是把正立的三角形与倒立的三角形分开考虑呢。
今天用这种方法想了一下A了,本来这次比赛上面三个题目是完全可以A的,以后做题要稳中求胜,做到一A。
代码
#include<stdio.h>
#include<string.h>
int main(void)
{
int i,j,k,n,s;
while(scanf("%d",&n)==1)
{
s=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
s=s+j;
}
}
for(i=n-1;i>=1;i--,i--)
{
for(j=1;j<=i;j++)
{
s=s+j;
}
}
printf("%d
",s);
}
return 0;
}