Codeforces 241 div2题解

来源:互联网 发布:寻秦ol源码 编辑:程序博客网 时间:2024/04/24 18:41

这场题不难,但是自己逗逼没办法。。。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个-1ans++;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]);}




0 0
原创粉丝点击