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