zoj 1101 Gamblers 为什么总是WA?
2010-12-05 22:31
543 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=101
一道被各种人认为简单题的题,但是我WA了将近10次,我觉得有必要写出来,以供有需要的人参考。
这道题就是暴力解,需要的只是少量的优化,但是在优化过程中还是出了很多问题,其中的逻辑需要很严密。从另一方面可以看到ZOJ内部的测试数据很bt。好了,下面就贴上我改了很多仍然WA的代码,照着代码来分析一些容易出错的地方。
好了,我们一点点慢慢看:
sort,我没有做过实验,不sort会不会错,不过题目没有明确表示input数据是排序过的,虽然example是不降序排列的
i循环处和j循环处,这两个地方都是因为没有充分考虑负数情况。在i循环处,i>=3是基于bets[i]是三者之和,因此习惯性的以为它(bets[i])是最大的,但是由于可以有负数,因此它不一定是最大的,只能确定它一定不是最小的。
在j循环处,由于存在负数bet,所以i不是最大的,所以j非常可能比i大(循环中的逻辑决定了j>k>l,所以只需要在j循环中修改即可)。由于这个地方的改动,需要在k循环内部再加入if(i==j || i==k )的判断
循环内部比较判断处。if(tmp2 == bets[j] || tmp2 == bets[k])。这样的判断初看貌似是对的,至少我是这么觉得,但是忘记了可能bets[k] == bets[l]的情况。其他情况不会出现问题,因为bets[j] >= bets[k] >= bets[l](j>k>l)。所以判断应该取消,不需要判断。
好了,大致就这几个地方,下面贴一下最终acc的代码,可能依然有逻辑错误,欢迎指正^^。
至于
#ifndef ONLINE_JUDGE
freopen("input.txt", "rt", stdin);
freopen("output.txt", "wt", stdout);
#endif
如果要自己本地执行代码,就新建个INPUT.TXT,或者直接注释掉这几句。
还有我用了GOTO,我只是比较懒的在每层loop里面做判断,所以请谅解。
一道被各种人认为简单题的题,但是我WA了将近10次,我觉得有必要写出来,以供有需要的人参考。
这道题就是暴力解,需要的只是少量的优化,但是在优化过程中还是出了很多问题,其中的逻辑需要很严密。从另一方面可以看到ZOJ内部的测试数据很bt。好了,下面就贴上我改了很多仍然WA的代码,照着代码来分析一些容易出错的地方。
#include <iostream> #include<stdio.h> #include<vector> #include<algorithm> using namespace std; int main() { #ifndef ONLINE_JUDGE freopen("input.txt", "rt", stdin); freopen("output.txt", "wt", stdout); #endif long n; long tmp; vector<long> bets; cin >> n; while(n!=0) { bets.clear(); for(long i=0;i<n;i++) { cin >> tmp; bets.insert(bets.end(),tmp); } //Please sort, we never know whether the data is sorted, although the example is. sort(bets.begin(), bets.end()); bool flag = false; int i; /********************************************** //The loop exists one important problem: //There are Negative bets. So the j,k bets may larger than i bets! //So not start from j=i-1 //It should loop through all bets /********************************************************** //Ok, there are another problem: i>=3 //Think when bets[0] is a very negative number, so we need some positive j and k when l = 0 //The situation i=1 exists. So the code should be i>=1 */ for(i=n-1;i>=3;i--) for(int j=i-1;j>=2;j--) for(int k=j-1;k>=1;k--) { long tmp2 = bets[i] - bets[j] - bets[k]; //Here also exist problem: //When two bets are the same(bets[k] == bets[l]) //The answer will lose. because we just continue if(tmp2 == bets[j] || tmp2 == bets[k]) { continue; } for(int l = k-1;l>=0;l--) { if(tmp2 == bets[l]) { flag = true; goto OUTER; } else if(tmp2 > bets[l]) { break; } } } OUTER: if(flag) { cout << bets[i] << endl;; } else { cout << "no solution" <<endl; } cin >> n; } return 0; }
好了,我们一点点慢慢看:
sort,我没有做过实验,不sort会不会错,不过题目没有明确表示input数据是排序过的,虽然example是不降序排列的
i循环处和j循环处,这两个地方都是因为没有充分考虑负数情况。在i循环处,i>=3是基于bets[i]是三者之和,因此习惯性的以为它(bets[i])是最大的,但是由于可以有负数,因此它不一定是最大的,只能确定它一定不是最小的。
在j循环处,由于存在负数bet,所以i不是最大的,所以j非常可能比i大(循环中的逻辑决定了j>k>l,所以只需要在j循环中修改即可)。由于这个地方的改动,需要在k循环内部再加入if(i==j || i==k )的判断
循环内部比较判断处。if(tmp2 == bets[j] || tmp2 == bets[k])。这样的判断初看貌似是对的,至少我是这么觉得,但是忘记了可能bets[k] == bets[l]的情况。其他情况不会出现问题,因为bets[j] >= bets[k] >= bets[l](j>k>l)。所以判断应该取消,不需要判断。
好了,大致就这几个地方,下面贴一下最终acc的代码,可能依然有逻辑错误,欢迎指正^^。
#include <iostream> #include<stdio.h> #include<vector> #include<algorithm> using namespace std; int main() { #ifndef ONLINE_JUDGE freopen("input.txt", "rt", stdin); freopen("output.txt", "wt", stdout); #endif long n; long tmp; vector<long> bets; cin >> n; while(n!=0) { bets.clear(); for(long i=0;i<n;i++) { cin >> tmp; bets.insert(bets.end(),tmp); } sort(bets.begin(), bets.end()); bool flag = false; int i; for(i=n-1;i>=1;i--) for(int j=n-1;j>=2;j--) for(int k=j-1;k>=1;k--) { long tmp2 = bets[i] - bets[j] - bets[k]; if(i==j || i==k ) { continue; } for(int l = k-1;l>=0;l--) { if(tmp2 == bets[l]) { flag = true; goto OUTER; } else if(tmp2 > bets[l]) { break; } } } OUTER: if(flag) { cout << bets[i] << endl;; } else { cout << "no solution" <<endl; } cin >> n; } return 0; }
至于
#ifndef ONLINE_JUDGE
freopen("input.txt", "rt", stdin);
freopen("output.txt", "wt", stdout);
#endif
如果要自己本地执行代码,就新建个INPUT.TXT,或者直接注释掉这几句。
还有我用了GOTO,我只是比较懒的在每层loop里面做判断,所以请谅解。
相关文章推荐
- ZOJ1101-Gamblers 终于AC。。。
- ZOJ 1101 Gamblers (A=B+C+D)
- zoj 1101 Gamblers(快排+二分)
- zoj_1101_Gamblers_枚举_hash
- ZOJ-1101-Gamblers
- 杭电acm2007,为什么总是WA?
- zoj1101 Gamblers
- ZOJ 1101 Gamblers
- ZOJ 1101 Gamblers
- zoj 1101 Gamblers
- zoj 1101 Gamblers
- ZOJ Problem Set–1101 Gamblers
- ZOJ 1101 Gamblers (简单搜索)
- ZOJ 1101 Gamblers
- ZOJ 1101Gamblers
- ZOJ 1101 Gamblers
- zoj 1101 Gamblers
- ZOJ2110/HUD1010骨头的诱惑(HDUAC2,ZOJWA但是不知道为什么。。。)
- ZOJ 1101 Gamblers 二分
- chapter05-Gamblers(ZOJ 1101)