这场题不难,但是自己逗逼没办法。。。rating又跌。
前两题略水,直接搞就可以了。
第三题:其实就是很简单的贪心嘛。序号的问题被hack了。订单按照金钱降序排,桌子按照容量生序排,然后为每个订单去贪心找解即可。这里我犯了个脑残错误,排序的时候原序号要保留,所以都要建结构体再排。
第四题:很好的一道模拟题。比赛的时候没看到等差数列一定要连续,就一直不知道怎么搞,以为是神题,赛后发现理解错题意了。不过这也是不好做的,情况特别多,讨论及其复杂,我赛后WA了无数炮才过,真是模拟题中的好题。推荐做!
#include <cstdio> #include <algorithm> typedef long long ll; using namespace std; int main(){ int n; ll tt = -(1e9 + 7); //被这个常量卡,一开始设置的是1e9 + 7,其实这个数是有可能达到的。。。 ll pre = tt, d = tt; //这里被ll卡,一开始用的int,其实是可以到ll的。 int cou1 = 0, cou2 = 0, ans = 0; scanf("%d", &n); for(int i = 0; i < n; i++){ ll tmp = 0; scanf("%I64d", &tmp); if(tmp == -1){ if(pre == tt){ pre = -1; d = tt; cou1 = 1; cou2 = 0; ans++; } else{ if(d == tt) { cou1++; } else{ if(pre + d <= 0){ pre = -1; d = tt; cou1 = 1;//这里一开始没有将cou1置1,被13 2 -1 3 1 3 1 -1 1 3 -1 -1 1 1这组数据卡 cou2 = 0; ans++; } else pre = pre + d; } } } else{ if(pre == tt){ pre = tmp; d = tt; cou1 = cou2 = 0; ans++; } else{ if(d == tt){ if(pre == -1){ pre = tmp; cou2 = cou1; cou1 = 0; } else if((tmp - pre) % (cou1 + 1) == 0){ d = (tmp - pre) / (cou1 + 1); //一开始笔误/写成% if(pre - d * cou2 <= 0){ //注意这里要记录cou2表示的是pre之前还有cou2个-1 ans++; pre = tmp; d = tt; //d要初始化 cou1 = cou2 = 0; } else{ pre = tmp; cou1 = cou2 = 0; } } else{ ans++; pre = tmp; cou1 = cou2 = 0; d = tt; } } else{ if(tmp != pre + d){ ans++; pre = tmp; cou1 = cou2 = 0; d = tt; } else pre = tmp; } } } } printf("%d\n", ans); return 0; }
第五题:图论题。比赛的时候最后一个小时就想这个题了,一开始思路是对的,枚举每个点然后求出这个点到其他点的最短路径边条数。先球最短路,然后在求边数的时候被卡住了。。。没搞出来。赛后看到别人的代码,感觉思路很好,记下来。先求最短路,然后求出一步到达这个点的最短路边数,其实就把图变成有向图了,然后枚举每个点,如果这个点可以在最短路径上,就将它的一步到达边加进来即可。总体复杂度o(n^3)。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 505; const int INF = 0x3f3f3f3f; int n, m, e[N][N], f[N][N], c[N][N]; int main() { memset(e, 0x3f, sizeof(e)); scanf("%d%d", &n, &m); for (int a, b, l, i = 0; i < m; ++i) { scanf("%d%d%d", &a, &b, &l); --a, --b; e[a][b] = e[b][a] = l; } memcpy(f, e, sizeof(f)); for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) f[i][j] = min(f[i][j], f[i][k] + f[k][j]); for (int i = 0; i < n; ++i) f[i][i] = 0; for (int i = 0; i < n; ++i) { int cnt[N] = {}; for (int j = 0; j < n; ++j) if (f[j][i] != INF) for (int k = 0; k < n; ++k) if (e[j][k] + f[k][i] == f[j][i]) cnt[j]++; for (int j = 0; j < i; ++j) if (f[j][i] != INF) for (int k = 0; k < n; ++k) if (f[j][k] + f[k][i] == f[j][i]) c[j][i] += cnt[k]; } for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) printf("%d ", c[i][j]); }
Codeforces 241 div2题解,布布扣,bubuko.com
原文:http://blog.csdn.net/waitfor_/article/details/23758003