一本通上数据测试点比较简单,很容易AC。
原版UVA上很麻烦,好久才AC。百度上搜不到原版题目的题解。洛谷上也没有人AC,更没有题解。
特地发布一下我的题解,供大家一起学习研究。
这是洛谷题解连接:
https://www.luogu.com.cn/problemnew/solution/UVA10203
以下是洛谷我发的题解原文。
这题很费时,都是细节问题。分享一下思路和代码,一起学习研究。
简单介绍一下思路:有数据的保证,一定构成欧拉回路后者欧拉路。从起始点出发,走一个欧拉路或者欧拉回路,然后沿着反方向返回,这样保证都在铲雪的路上。
数据输入很特别,不能使用常规的数值输入。原题给定数据组后面有一个空白行,每组数据之间也有一个空白行。如果用常规数值读入数据,会跨行读入,没有办法知道空白行的位置。所以这里采用字符串读入,读入空白行时,手工判断,读入结束符时,结果为NULL。然后再手动把串转换为数值即可。文件测试数据,输入最后一行不要加回车。
数据输出也很特别,原版英文题目明确要求,每行输出后要一个空白行,这个很容易被忽视。
我最后在这一组测试数据上没有通过,建议大家都测试一下,是不是问题也出在这里,很容易被忽视的细节:
-
2 0 0 0 0 10000 10000 5000 -10000 5000 10000 5000 10000 10000 10000 0 0 0 0 0 9950
-
观察后面一组测试数据,如果输出: 00:60,那就错了。
应该是: 1:00。这个细节让我费尽心思。
-
这里提交代码AC的代码:
-
/* 因为可以U型掉头,所以沿着出发的路径相反的路, 一定可以回到出发点。不需要空车前进 。 AC代码 */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define maxn 500 double ans=0;//ans:铲雪距离 char s[maxn]; int blank[4];//字符数组中,三个空格的位置 //从idx开始,把s中的字符转换为数字 bool first=true;//第一组结果 long long to_data(int idx){ long long t=0; int flag=1; if(s[idx]=='-'){ //负数 flag=-1; idx++; } while(s[idx]>='0' && s[idx]<='9'){ t=t*10+(s[idx]-'0'); idx++; } return flag*t; } //计数s中的空格数 int blank_cnt(){ int i=0,cnt=0; int blank_i=1;//空格的坐标位置 while(s[i]){ if(s[i]==' '){ cnt++; blank[blank_i++]=i; } i++; } return cnt; } //主功能 void resolve(){ //双车道,距离乘以2 ans*=2; ans/=1000;//单位变成千米 double time=0;//单位是小时 time=ans/20; long long hour=floor(time); long long minute=((time-hour)*60+0.5); //四舍五入后够60分钟,小时加1,分钟清零 if(minute==60){ minute=0; hour++; } if(first){ //第一组结果输出 printf("%lld:%02lld\n",hour,minute); first=false; }else{ //先输出一个空白行 printf("\n%lld:%02lld\n",hour,minute); } } int main(){ // freopen("1374.in","r",stdin); // freopen("1374.out","w",stdout); int t,cnt; long long x1,y1,x2,y2; bool first=true;//第一组数据 scanf("%d",&t); getchar();//消耗多余的回车键 getchar();//空白行的回车 while(true){ //在UVA网站,gets已经废弃,不能使用。这里改用fgets。 //输入结束 if(fgets(s,maxn,stdin)==NULL) break; cnt=blank_cnt() ;//计算空格个数 //开始坐标位置,说明开始一组新的数据输入。直到下一次cnt==1截止 if(cnt==1){ //数据本身可以不需要,不作处理 //一组数据开始 //数据初始化 ans=0; }else if(cnt==3){ //新的数据输入,分离出四个正数 x1=to_data(0) ; y1=to_data(blank[1]+1); x2=to_data(blank[2]+1); y2=to_data(blank[3]+1); //计算顶点间的距离,这是铲雪必须的距离 ans+=sqrt(pow((x1-x2),2.0)+pow((y1-y2),2.0)); }else{ //空白行,一组数据结束,处理数据 resolve(); } } //处理最后一组数据输出 resolve(); return 0; }