目 录

  • 2016-04
    • 折点计数
    • 俄罗斯方块
    • 路径解析
    • 游戏
    • 网络连接
  • 2016-09
    • 最大波动
    • 火车购票
    • 炉石传说
    • 交通规划
    • 祭坛
  • 2016-12
    • 中间数
    • 工资计算
    • 权限查询
    • 压缩编码
  • 2017-03
    • 分蛋糕
    • 学生排队
    • Markdown
    • 地铁修建
    • 引水入城
  • 2017-09
    • 打酱油
    • 公共钥匙盒
    • JSON查询
    • 通信网络
    • 除法
  • 2017-12
    • 最小差值
    • 游戏
    • Crontab
    • 行车路线
    • 商路
  • 2018-03
    • 跳一跳
    • 碰撞的小球
    • URL映射
    • 棋局评估
    • 二次求和
  • 2018-09
    • 卖菜
    • 买菜
  • 2018-12
    • 小明上学
    • 小明放学
    • CIDR合并
    • 数据中心
    • 管道清洁

2016-04

折点计数

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int a[maxn] = { 0 };
int main() {int n;int i;int num = 0;scanf("%d",&n);for (i = 0; i < n; i++){scanf("%d",&a[i]);}for (i = 1; i < n - 1; i++){if( (a[i]<a[i - 1] && a[i]<a[i + 1] )||( a[i]>a[i - 1] && a[i]>a[i + 1]))num++;}printf("%d",num);return 0;
}

俄罗斯方块


这一题注意不能只对比最后一行有效行,需要对比b中的所有行才可以,同时最后一行有冲突,和没有行有冲突,这两种情况是不一样的。

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;int a[16][11];
int b[5][5];
int main() {int n;int i,j;int k;//输入变量for(i=1;i<=15;i++)for (j = 1; j <=10; j++){scanf("%d",&a[i][j]);}for (i = 1; i <= 4; i++)for (j = 1; j <= 4; j++){scanf("%d",&b[i][j]);}scanf("%d",&n);//第n列//下面找有冲突的行和列int ctRow=0;//数组a中的冲突行int ctRow1;//数组b中的冲突行int row;//数组b有效的行数int hang = 1;//循环变量//记录下b[][]中不为1的最下面一行rowfor (i = 4; i >= 1; i--)//从下向上遍历{     if (b[i][1] != 0||b[i][2]!=0||b[i][3]!=0||b[i][4]!=0){row = i;break;}}//不断向下直到走不动!注意这里容易出错,不能只看最后一行有没有冲突,要遍历1-row行,j即是有冲突的行for (i = 1; i+row-1 <=15; i++){hang = 1;for (j = i; j <= i + row-1; j++){//printf("现在对比到数组a第%d行,数组b第%d行\n",j,hang);if (a[j][n] + b[hang][1] == 2 || a[j][n + 1] + b[hang][2] == 2 || a[j][n + 2] + b[hang][3] == 2 || a[j][n + 3] + b[hang][4] == 2){//printf("!!!\n");ctRow = j;ctRow1 = hang;break;                }hang++;}if (ctRow !=0)break;            }if (ctRow == 0)//如果一直没有冲突{j = 15-row+1;for (hang=1; hang <= row;hang++ )//一共ctRow行{a[j][n] += b[hang][1]; a[j][n + 1] += b[hang][2]; a[j][n + 2] += b[hang][3]; a[j][n + 3] += b[hang][4];           j++;}}else//如果有冲突的行{hang = 1;j = ctRow -ctRow1;for (; hang <= row; )//一共ctRow行{a[j][n] += b[hang][1]; a[j][n + 1] += b[hang][2]; a[j][n + 2] += b[hang][3]; a[j][n + 3] += b[hang][4];hang++;j++;}}//输出结果for (i = 1; i <= 15; i++){for (j = 1; j <= 10; j++){printf("%d ", a[i][j]);}printf("\n");}        return 0;
}

路径解析

其实当前路径+相对路径就是绝对路径了!
然后如果/…/出现在一开始,就直接删掉。
如果/…/出现在中间,就把前面的上一个目录删掉即可

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
using namespace std;
//路径解析
string str;//当前目录
string tempstr;//临时的需要正规化的路径
int main() {int n;scanf("%d", &n);getchar();getline(cin, str);for (int i = 0; i < n; i++){getline(cin, tempstr);//getline可以输入空字符串       if (tempstr.length() == 0)//如果是空字符串,直接输出当前路径{          tempstr = str;}else{if (tempstr[0] == '/');//说明是绝对路径,无需操作elsetempstr = str + "/" + tempstr;//是相对路径,将相对路径变成绝对路径int fd=0;while ((fd = tempstr.find("/../")) != -1){if (fd == 0)tempstr.replace(fd, 4, "/");else{int fd2 = tempstr.rfind("/", fd - 1);tempstr.erase(fd2, fd - fd2 + 3);}}fd = 0;while ((fd = tempstr.find("/./")) != -1){tempstr.replace(fd, 3, "/");}         fd = 0;while ((fd = tempstr.find("//")) != -1){tempstr.replace(fd, 2, "/");}         fd = 0;            if(tempstr.length() > 1&&tempstr[tempstr.length() - 1] == '/')//如果最后一个是/,那么删掉{                tempstr.erase(tempstr.length() - 1, 1);//删掉最后一个}}cout << tempstr << endl;}return 0;
}

游戏


这道题目又是一眼BFS,不设置Inq数组,因为还可以走回去,但是这样会超时,只有20分

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
const int maxn = 110;//边长最大110
struct node {int x, y;int t1, t2;//开始危险时间和结束危险时间int t;
}matrix[maxn][maxn],Node;//二维矩阵
int X[4] = {0,0,1,-1};
int Y[4] = {1,-1,0,0};
int n, m;//n是行数和m是列数
int t;//有危险的方格数量
bool judge(int x, int y,int t)
{if (x > n || x<1 || y>m || y < 1) return 0;//行数和列数if (t >= matrix[x][y].t1 && t <= matrix[x][y].t2) return 0;//还是危险的   return 1;}
int BFS()
{queue<node> Q;Node.x = 1; Node.y = 1; Node.t = 0;//当前时刻是0Q.push(Node);   while (!Q.empty())//队列不为空时{node top = Q.front();//最前面的元素if (top.x == n && top.y == m){return top.t;}Q.pop();for (int i = 0; i < 4; i++){int newX = top.x + X[i];int newY = top.y + Y[i];matrix[newX][newY].t = top.t + 1;if (judge(newX, newY, matrix[newX][newY].t)){// printf("时刻%d->(%d,%d)\n", matrix[newX][newY].t, newX, newY);Node.x = newX;Node.y = newY;Node.t = matrix[newX][newY].t;Q.push(Node);              }}}return -1;
}
int main()
{  int r, c, a, b;scanf("%d %d %d",&n,&m,&t);//初始化地图for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){matrix[i][j].x = i;matrix[i][j].y = j;matrix[i][j].t1 = INT_MAX;matrix[i][j].t2 = INT_MIN;}}for (int i = 0; i < t; i++){scanf("%d %d %d %d",&r,&c,&a,&b);matrix[r][c].t1 = a;matrix[r][c].t2 = b;}int ans= BFS();printf("%d\n",ans);return 0;
}

设置一个inq[x][y][t]数组,表示t时刻是否到达过(x,y),如果到达过就不用重复到达,这样就不会超时了

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
const int maxn = 110;//边长最大110
struct node {int x, y;int t1, t2;//开始危险时间和结束危险时间int t;
}matrix[maxn][maxn],Node;//二维矩阵
int X[4] = {0,0,1,-1};
int Y[4] = {1,-1,0,0};
bool inq[maxn][maxn][10010];//时间t下是否到达过该坐标
int n, m;//n是行数和m是列数
int t;//有危险的方格数量
bool judge(int x, int y,int t)
{if (x > n || x<1 || y>m || y < 1) return 0;//行数和列数if (t >= matrix[x][y].t1 && t <= matrix[x][y].t2) return 0;//还是危险的  if (inq[x][y][t] == 1) return 0;return 1;}
int BFS()
{queue<node> Q;Node.x = 1; Node.y = 1; Node.t = 0;//当前时刻是0Q.push(Node);   inq[1][1][0] = 1;while (!Q.empty())//队列不为空时{node top = Q.front();//最前面的元素if (top.x == n && top.y == m){return top.t;}Q.pop();for (int i = 0; i < 4; i++){int newX = top.x + X[i];int newY = top.y + Y[i];matrix[newX][newY].t = top.t + 1;if (judge(newX, newY, matrix[newX][newY].t)){// printf("时刻%d->(%d,%d)\n", matrix[newX][newY].t, newX, newY);Node.x = newX;Node.y = newY;Node.t = matrix[newX][newY].t;inq[Node.x][Node.y][Node.t] = 1;Q.push(Node);              }}}return -1;
}
int main()
{  int r, c, a, b;scanf("%d %d %d",&n,&m,&t);//初始化地图// fill(inq[0],inq[0]+maxn*maxn*10010,0);for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){matrix[i][j].x = i;matrix[i][j].y = j;matrix[i][j].t1 = INT_MAX;matrix[i][j].t2 = INT_MIN;}}for (int i = 0; i < t; i++){scanf("%d %d %d %d",&r,&c,&a,&b);matrix[r][c].t1 = a;matrix[r][c].t2 = b;}int ans= BFS();printf("%d\n",ans);return 0;
}

网络连接


样例输入:

5
20 93 6
11111111111111111111
1 2 727765
2 3 263881
1 4 514909
2 4 131844
3 4 933178
1 5 438613
2 5 603733
3 5 859906
4 5 38725
1 6 599082
2 6 225184
3 6 365575
4 6 126126
5 6 25505
2 7 546601
3 7 63931
4 7 419406
5 7 531790
6 7 265271
2 8 724126
3 8 163879
4 8 59317
5 8 545880
6 8 126779
7 8 938859
4 9 387231
5 9 600880
6 9 927742
7 9 56690
8 9 987324
4 10 23106
5 10 328383
6 10 757082
7 10 787341
8 10 218539
9 10 282814
5 11 506005
6 11 257575
7 11 524808
8 11 223439
9 11 402018
10 11 580131
6 12 711292
7 12 314072
8 12 752595
9 12 141042
10 12 339498
11 12 321201
7 13 100337
8 13 969444
9 13 683912
10 13 973527
11 13 776443
12 13 436444
8 14 826460
9 14 453950
10 14 231374
11 14 667343
13 14 754318
10 15 46540
11 15 741941
12 15 909374
13 15 901791
14 15 246817
10 16 34192
11 16 866848
12 16 488324
13 16 824636
14 16 319615
15 16 472537
11 17 661823
12 17 595773
13 17 912773
14 17 674733
15 17 880787
16 17 168668
12 18 621903
13 18 894662
14 18 994829
15 18 80344
16 18 343121
17 18 697098
13 19 569872
14 19 599332
15 19 417377
16 19 837022
18 19 270641
14 20 748579
15 20 724926
16 20 367572
17 20 103857
18 20 443540
19 20 932348
20 92 6
00000010000000001000
1 2 113099
1 3 587351
2 3 209419
1 4 412024
2 4 526550
3 4 74575
1 5 627809
2 5 488889
3 5 78667
4 5 853953
1 6 914999
2 6 60305
3 6 52666
4 6 39394
5 6 243622
1 7 843636
2 7 752452
3 7 206953
4 7 209536
5 7 105503
6 7 179097
2 8 938375
3 8 449664
4 8 464591
5 8 312120
6 8 943383
7 8 798642
3 9 759837
4 9 655902
5 9 367024
6 9 560174
7 9 421235
8 9 552637
4 10 251605
5 10 453809
6 10 942947
7 10 378285
8 10 944748
9 10 761726
5 11 7926
6 11 237034
8 11 860297
9 11 224152
10 11 62671
7 12 518894
9 12 265459
10 12 399585
11 12 16993
7 13 935813
8 13 675125
9 13 986248
10 13 801332
11 13 775825
12 13 483974
8 14 879925
9 14 568657
10 14 539371
11 14 392819
12 14 673171
13 14 593981
9 15 893512
10 15 459005
11 15 935151
13 15 984026
14 15 352506
10 16 847405
11 16 902823
12 16 924659
14 16 31185
15 16 83802
11 17 225697
12 17 697702
13 17 431672
14 17 934227
15 17 64055
16 17 714592
12 18 429691
13 18 69217
16 18 916446
17 18 859123
13 19 675753
14 19 427831
15 19 3386
16 19 179655
17 19 148897
18 19 307554
14 20 291004
15 20 497622
16 20 669001
17 20 742221
18 20 662204
19 20 966218
20 93 6
00000101001110000010
1 2 710445
1 3 390108
2 3 871795
1 4 323940
2 4 1557
3 4 853515
1 5 987497
2 5 791951
3 5 565856
4 5 401932
1 6 49223
2 6 59889
3 6 300678
4 6 123895
5 6 160344
1 7 196308
3 7 787087
5 7 224478
6 7 104395
3 8 344509
4 8 173377
5 8 100930
7 8 544113
3 9 475119
4 9 673881
5 9 234187
6 9 191885
7 9 35559
8 9 872991
4 10 339910
5 10 624600
6 10 442925
7 10 821981
8 10 805172
9 10 463188
5 11 745511
6 11 444346
7 11 856170
8 11 10706
9 11 582739
10 11 666926
6 12 838187
7 12 711050
8 12 386931
9 12 886249
10 12 356669
11 12 14156
7 13 339092
8 13 578454
9 13 195419
10 13 600017
11 13 504670
12 13 753722
8 14 219160
9 14 281523
10 14 730539
11 14 890253
12 14 789909
13 14 995665
9 15 227552
10 15 125146
11 15 737706
12 15 697809
13 15 753633
14 15 248107
10 16 15962
11 16 178154
12 16 586355
13 16 32073
14 16 912542
15 16 913266
11 17 158548
12 17 35601
14 17 818081
15 17 39970
16 17 330500
12 18 207654
13 18 729538
14 18 642935
15 18 73734
16 18 676418
17 18 455930
13 19 945333
15 19 723755
16 19 67978
17 19 128589
18 19 647790
14 20 294150
15 20 681124
16 20 749167
17 20 480962
18 20 133266
19 20 928077
20 34 2
10000111010111001100
1 2 175025
1 3 372293
2 3 723523
2 4 828462
3 4 96614
3 5 496039
4 5 435856
4 6 728072
5 6 26736
5 7 658831
6 7 294479
6 8 971178
7 8 755365
7 9 467364
8 9 912893
8 10 88692
9 10 132051
9 11 939008
10 11 986048
11 12 676052
11 13 287187
12 13 304051
13 14 305223
14 15 610873
14 16 540274
15 16 494014
15 17 90777
16 17 157248
16 18 211384
17 18 718096
17 19 822166
18 19 366585
18 20 250962
19 20 231236
20 89 6
00110010100101111001
1 2 758268
1 3 205716
2 3 295263
1 4 207862
2 4 69876
3 4 179798
2 5 479889
3 5 953848
4 5 68337
1 6 833892
2 6 234107
4 6 772558
5 6 675566
2 7 942986
3 7 253909
4 7 95158
5 7 119424
6 7 316766
2 8 477692
3 8 406515
4 8 987774
5 8 808702
6 8 184409
7 8 500278
3 9 887393
4 9 469162
6 9 293078
7 9 205359
8 9 777079
5 10 313301
6 10 636761
7 10 846529
8 10 315392
9 10 477016
5 11 29206
6 11 840608
7 11 151527
8 11 877001
9 11 439665
10 11 907197
7 12 815137
8 12 530916
9 12 922868
11 12 827381
7 13 887939
8 13 638323
9 13 311582
10 13 169399
11 13 763999
12 13 695711
8 14 686748
9 14 400272
10 14 39935
11 14 528026
12 14 776064
13 14 965438
10 15 457267
12 15 318406
13 15 3489
14 15 217063
11 16 763755
12 16 711741
13 16 617167
14 16 469274
15 16 845875
11 17 776936
12 17 464487
13 17 682511
14 17 11831
15 17 447702
16 17 10247
12 18 10991
13 18 388512
14 18 312431
15 18 427326
16 18 846191
17 18 977005
13 19 941472
14 19 709497
15 19 343667
16 19 346238
17 19 777055
18 19 703066
14 20 779760
15 20 559561
16 20 810681
17 20 436275
18 20 371192
19 20 42384

样例输出:

2402044
339126
523926
4622029
1721412

抽象为建立最小生成树,并且要满足所有用户设备相互连通。
暂时没有代码

2016-09

最大波动

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 10000;
int a[maxn] = { 0 };
int main() {int n;scanf("%d",&n);int max = 0;int temp;for (int i = 0; i < n; i++){scanf("%d",&a[i]);}for (int i = 0; i < n-1; i++){temp = abs(a[i + 1] - a[i]);if (temp > max)max = temp;        }printf("%d",max);return 0;
}

火车购票


解法1:

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
int a[21][6];//20排,每排5个座位
int main() {int n;int i, num,j;int hang, lie;int flag;//=0表示没有找到连号的座位,反scanf("%d",&n);for (i = 1; i <=20; i++)for (j = 1; j <=5; j++)           a[i][j] = 1;//表示有座位for (i = 0; i < n; i++){flag = 0;scanf("%d",&num);//下面找合适的座位;if (num == 1){for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5; lie++){if (a[hang][lie] == 1){printf("%d\n", (hang - 1) * 5 + lie);a[hang][lie] = 0;flag=1;break;}                 }if (flag == 1)                   break;}}else if (num == 2){for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5-num+1; lie++){if (a[hang][lie] == 1 && a[hang][lie + 1] == 1){flag = 1;printf("%d %d\n",(hang - 1) * 5 + lie, (hang - 1) * 5 + lie+1);a[hang][lie] = 0;a[hang][lie + 1] = 0;break;}}if (flag == 1)break;}if (flag == 0)//没有找到连续的座位{for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5 ; lie++){if (a[hang][lie] == 1){printf("%d ", (hang - 1) * 5 + lie);a[hang][lie] = 0;num--;}if (num == 0){printf("\n");break;}}if (num == 0)break;}}}else if (num == 3){for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5 - num + 1; lie++){if (a[hang][lie] == 1 && a[hang][lie + 1] == 1&&a[hang][lie+2]==1){flag = 1;printf("%d %d %d\n", (hang - 1) * 5 + lie, (hang - 1) * 5 + lie + 1, (hang - 1) * 5 + lie + 2);a[hang][lie] = 0;a[hang][lie + 1] = 0;a[hang][lie + 2] = 0;break;}}if (flag == 1)break;}if (flag == 0)//没有找到连续的座位{for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5; lie++){if (a[hang][lie] == 1){printf("%d ", (hang - 1) * 5 + lie);a[hang][lie] = 0;num--;}if (num == 0){printf("\n");break;}}if (num == 0)break;}}}else if (num == 4){for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5 - num + 1; lie++){if (a[hang][lie] == 1 && a[hang][lie + 1] == 1 && a[hang][lie + 2] == 1&& a[hang][lie + 3] == 1){flag = 1;printf("%d %d %d %d\n", (hang - 1) * 5 + lie, (hang - 1) * 5 + lie + 1, (hang - 1) * 5 + lie + 2, (hang - 1) * 5 + lie + 3);a[hang][lie] = 0;a[hang][lie + 1] = 0;a[hang][lie + 2] = 0;a[hang][lie + 3] = 0;break;}}if (flag == 1)break;}if (flag == 0)//没有找到连续的座位{for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5; lie++){if (a[hang][lie] == 1){printf("%d ", (hang - 1) * 5 + lie);a[hang][lie] = 0;num--;}if (num == 0){printf("\n");break;}}if (num == 0)break;}}}else{for (hang = 1; hang <= 20; hang++){if (a[hang][1] == 1 && a[hang][2] == 1 && a[hang][3] == 1&&a[hang][4]==1&&a[hang][5]==1){flag = 1;printf("%d %d %d %d %d\n", (hang - 1) * 5 + 1, (hang - 1) * 5 + 2, (hang - 1) * 5 +3, (hang - 1) * 5 + 4, (hang - 1) * 5 + 5);a[hang][1] = 0;a[hang][2] = 0;a[hang][3] = 0;a[hang][4] = 0;a[hang][5] = 0;break;}         }if (flag == 0)//没有找到连续的座位{for (hang = 1; hang <= 20; hang++){for (lie = 1; lie <= 5; lie++){if (a[hang][lie] == 1){printf("%d ", (hang - 1) * 5 + lie);a[hang][lie] = 0;num--;}if (num == 0){printf("\n");break;}}if (num == 0)break;}}}}return 0;
}

解法2

#include<iostream>using namespace std;struct Seat
{int id;//座位的编号 int status;//座位的状态
};int main()
{int n;//购票指令的数量cin >>n;Seat seat[22][7];//定义100个座位 int a=1;for(int i=1;i<=21;i++)//初始化座位 ,状态1表示已购买,0表示空座位 {for(int j=1;j<6;j++){seat[i][j].id=a++;seat[i][j].status=0;} }int people=0;//购票人数 int numOfTickets;//每个人购买票的数量 while(people <n){cin >>numOfTickets;int rows=1;//从第一行开始扫描,到最后一行 while(rows<=20){int countSeats=0;//统计每行空座位数量 for(int i=1;i<6;i++)//从对应行的第一个位置开始扫描,直到这一行最后一个位置 {if(seat[rows][i].status ==0){countSeats++; } }//cout <<"countSeat:"<<countSeats<<endl;if(numOfTickets <=countSeats)//当购买票数小于这一行空位置时候 {for(int i=1;i<6;i++){if(seat[rows][i].status == 0)//从当前不为空的位子开始输出票的位置 {for(int j=i;j<i+numOfTickets;j++){cout <<seat[rows][j].id<<" ";//输出票的位置seat[rows][j].status=1;//将座位状态置为1 }break;    //座位输出完后,结束循环 }}cout <<endl;break;//换下一个人开始购票 }else//当前行的座位数量小于购买者的票数 {if(rows==20)//到最后一行都没有连续的座位时,分配座位号小的的位置 {//cout <<"连续座位已满。为您分配空缺位置!"<<endl;int row=1;while(row<=20){for(int i=1;i<6;i++){if(seat[row][i].status==0){cout <<seat[row][i].id<<" ";seat[row][i].status=1;numOfTickets--;//输出一张票,票数就减小一张 if(numOfTickets ==0)//当没有购买者票数 时,就结束循环 {break;}}}if(numOfTickets ==0)//换置下一人,题目在这里没有说明当座位满的时候的情况怎么处理,//只需要考虑座位没有被安排完或者刚好安排完可 {break;}else//如果还有票数,就继续循环 ,知道,将票输出完。 {row++;}}cout <<endl;break;//当所有购买者票都输出之后,结束整个循环 }else//还有购买者是继续循环 {rows++;}}}people++;}return 0;
}

炉石传说

vector的妙用

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
struct node {int attack;int heath;node() {}node(int a, int b) {attack = a; heath = b;}
};
/*
* 1.vector中放置node来表示将军和随从
* 2.vector完美符和了当随从的id新加入时,vector.insert()右边的随从顺次向右移动一位
* 3.vector.erase()当删除某个随从时,左边的随从的编号都会减1
*/
vector<node> use[2];int main()
{string str;use[0].push_back(node(0, 30));//将军的attack为0,生命值为30use[1].push_back(node(0, 30));int n, id = 0;int flag = 0;//判断局面 scanf("%d", &n);//n轮操作while (n--){cin >> str;if (str == "end"){id = (id + 1) % 2;//当前的将军id序号continue;}if (str == "summon")//召唤随从{int a, b, c;cin >> a >> b >> c;//位置 攻击力 生命力 use[id].insert(use[id].begin() + a, node(b, c));//在a位置插入}if (str == "attack")//攻击的时候会导致一些死亡情况 {int a, b;cin >> a >> b;//召唤a 攻击b;//一开始60分处理一下这里就满分了    use[id][a].heath -= use[(id + 1) % 2][b].attack;;use[(id + 1) % 2][b].heath -= use[id][a].attack;//一定是随从攻击 ,所以id方的英雄不会死if (use[id][a].heath <= 0) use[id].erase(use[id].begin() + a);if (use[(id + 1) % 2][b].heath <= 0){//如果id=0,表示先手玩家,那么flag=1表示先手玩家获胜,如果id=1,表示后手玩家,那么flag=1表示后手玩家赢了if (b == 0) flag = id + 1;else use[(id + 1) % 2].erase(use[(id + 1) % 2].begin() + b);}}}if (flag == 1)//先手获胜printf("1\n");else if (flag == 0)//表示后手玩家获胜,flag==printf("0\n");else printf("-1\n");//游戏尚未结束//输出两个玩家情况for (int i = 0; i < 2; i++){printf("%d\n", use[i][0].heath);int len = use[i].size();printf("%d", len - 1);for (int j = 1; j < len; j++)printf(" %d", use[i][j].heath);printf("\n");}return 0;
}

交通规划


第一想法是求最小生成树,但是又要求到达首都的距离和原来一样短。
发现这题首先看要求到达首都的距离最短,可以知道是用DJ算法求最短路径,同时DJ算法里面的pre用来求前驱节点,在这里我们用DJ算法的pre[i]来求前面的路的最短长度
然后把pre[i]相加即可
第四题100分了!好激动呀

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
//这题的思路大概是dj算法求出每个节点的前继节点,然后计算和前面节点的边权相加即为结果
struct Node
{int v;//目标顶点int dis;//边权Node(int _v, int _dis) :v(_v), dis(_dis) {}
};
const int maxn = 10010;//最多Maxn个节点
vector<Node> Adj[maxn];
int n, m;//顶点数和边数
int d[maxn];//起点到各点的距离
bool vis[maxn] = { 0 };//有没有访问过
int pre[maxn];
const int INF = 1000000000;
void DFS(int s)
{fill(d,d+maxn,INF);for (int i = 1; i <= n; i++) pre[i] = 0;//与前驱的距离d[s] = 0;for (int i = 1; i <= n; i++){int u = -1, MIN = INF;for (int j = 1; j <= n; j++){if (vis[j] == 0 && d[j] < MIN){u = j;MIN = d[j];}}if (u == -1) return;vis[u] = 1;for (int j = 0; j < Adj[u].size(); j++){int v = Adj[u][j].v;if (vis[v] == 0  ){if (d[u] + Adj[u][j].dis < d[v]){d[v] = d[u] + Adj[u][j].dis;pre[v]= Adj[u][j].dis;}else if (d[u] + Adj[u][j].dis == d[v]){if(Adj[u][j].dis< pre[v])pre[v] = Adj[u][j].dis;}                                }}}
}
int main()
{int u, v,w;scanf("%d %d",&n,&m);//取得n和mfor (int i = 0; i < m;i++){scanf("%d %d %d",&u,&v,&w);Adj[u].push_back(Node(v,w));Adj[v].push_back(Node(u,w));//双向边}DFS(1);//记录前驱节点结束int ans=0;for (int i = 1; i <= n; i++){//printf("pre[%d]=%d",i,pre[i]);ans += pre[i];}printf("%d",ans);return 0;
}

祭坛

2016-12

中间数

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int maxn = 1010;
int a[maxn];
int main() {int n;scanf("%d",&n);int i,j;int left, right;for (i = 0; i < n; i++){scanf("%d",&a[i]);       }sort(a, a + n);//排序for (i = 0; i < n; i++){left = right = 0;for (j = 0; j < n; j++)if (a[j] < a[i])left++;else if (a[j] > a[i])right++;if (left == right){printf("%d",a[i]);return 0;}}printf("-1");return 0;
}

工资计算

这是一道数学题

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
#include<set>
using namespace std;int main() {int T;double S;scanf("%d",&T);if (T <= 3500)S = T;else if (T <= 4955)S = (T - 105) * 1.0 / 0.97;else if (T <= 7655)S = (T - 455) * 1.0 / 0.9;else if (T <= 11255)S = (T - 1255) * 1.0 / 0.8;else if (T <= 30755)S = (T - 1880) * 1.0 / 0.75;else if (T <= 44755)S = (T - 3805) * 1.0 / 0.7;else if (T <= 61005)S = (T - 6730) * 1.0 / 0.65;elseS = (T - 15080) * 1.0 / 0.55;//下面四舍五入//if (int(S) % 100 >= 50)//   S = (S / 100 + 1) * 100;//else//  S = (S / 100 ) * 100;printf("%g", S);//cout << S << endl;return 0;
}

权限查询


数据之间的嵌套很多:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <map>using namespace std;
/*
* 1.题目中有string->int的映射,使用Map来存储用map<string,int>来表示权限,<权限名,等级>//如果权限没有等级,那么等级变成-1
* 2.用vector里面存放结构体,表示用户与角色
* 3.结构体里面可以声明①名字②权限的map集合
* 4.可以用map<string, int>& refPriv = role.priv;来取得一个复制,对refPriv的操作也就是对role.priv的操作
* 5.当添加角色下全部权限时:遍历角色结构体的map
*/
typedef struct R {string name;map<string, int> priv;
}Role, User;vector<Role> roleVec;//用户
vector<User> userVec;//角色// pair<权限:等级>//当没有等级时,等级为-1
pair<string, int> category(string str) {int lev = -1;int len = str.length();if (len >= 3 && str[len - 2] == ':') {lev = str[len - 1] - '0';str = str.substr(0, len - 2);}return pair<string, int>(str, lev);
}int main(void) {int n;string str;// 输入权限定义// 因为测试用例保证合法所以用不上cin >> n;for (int i = 0; i < n; i++) {cin >> str;}// 输入角色定义cin >> n;int nn;for (int i = 0; i < n; i++) {Role role;cin >> role.name >> nn;map<string, int>& refPriv = role.priv;//取一个复制for (int j = 0; j < nn; j++) {cin >> str;pair<string, int> t_pair = category(str);// 如果权限重复,取最大值map<string, int>::iterator it = refPriv.find(t_pair.first);if (it != refPriv.end()) {//如果已经找到有这个权限了it->second = max(t_pair.second, it->second);}else {refPriv.insert(t_pair);//如果没有这个权限,就插入}}roleVec.push_back(role);//在角色列表插入这个角色}// 输入用户定义cin >> n;for (int i = 0; i < n; i++) {User user;cin >> user.name >> nn;map<string, int>& usrPriv = user.priv;//取一个复制for (int j = 0; j < nn; j++) {cin >> str;int len = roleVec.size();int k;// 查询角色是否存在for (k = 0; k < len; k++) {if (roleVec[k].name == str) {break;}}// 角色存在,添加角色下的全部权限if (k != len) {map<string, int>& rolePriv = roleVec[k].priv;for (map<string, int>::iterator it = rolePriv.begin(); it != rolePriv.end(); ++it) {//遍历角色的权限并插入// 权限重复则取最大值map<string, int>::iterator usr_it = usrPriv.find(it->first);if (usr_it != usrPriv.end()) {usr_it->second = max(usr_it->second, it->second);//如果权限存在}else {usrPriv.insert(pair<string, int>(it->first, it->second));}}}}userVec.push_back(user);//插入该角色}// 查询cin >> n;string name;for (int i = 0; i < n; i++) {cin >> name >> str;int len = userVec.size();int j;// 用户是否存在for (j = 0; j < len; j++) {if (userVec[j].name == name) {break;}}// 用户存在if (j != len) {map<string, int>& priv = userVec[j].priv;//priv表示用户权限集pair<string, int> cgy = category(str);// 用户是不是存在这个权限map<string, int>::iterator it = priv.find(cgy.first);// 权限存在if (it != priv.end()) {// 不带等级的查询if (cgy.second == -1) {if (it->second == -1) { // 权限就是不带等级的cout << "true" << endl;}else {  // 权限带等级cout << it->second << endl;}}else {  // 带等级查询if (cgy.second <= it->second) {cout << "true" << endl;}else {cout << "false" << endl;}}}else {  // 用户没有这个权限cout << "false" << endl;}}else {  // 没有这个用户cout << "false" << endl;}}return 0;
}

压缩编码

这题一眼哈夫曼树啊!本来以为是板子题,后来发现不是的,这个编码和haffman有区别,用haffman的板子可以拿10分
动态规划如下:

#include<iostream>
using namespace std;
const int INF = 1 << 30;
int dp[1010][1010],a[1010],sum[1010];
int n;
int main()
{int i,j,k,t;cin >>n;for(i=1;i<=n;i++){cin >> a[i];sum[i] = sum[i-1] + a[i];//用于指定区间内的计算总数 }//沿斜线扫描 for(j=2;j<=n;j++){for(i=1,k=j;i<=n-j+1;i++,k++){dp[i][k] = INF;for(t=i;t<k;t++){if(dp[i][k] > dp[i][t]+dp[t+1][k]+sum[k]-sum[i-1]){dp[i][k] = dp[i][t]+dp[t+1][k]+sum[k]-sum[i-1];}}}}cout << dp[1][n];return 0;
}

2017-03

分蛋糕


小模拟:

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 2010;
int main() {int n, k;scanf("%d %d",&n,&k);int num = 0;//最终分到蛋糕的数量int i;int temp;int sum = 0;for (i = 0; i < n; i++){scanf("%d", &temp);sum += temp;if (sum >= k){num++;if (i == n - 1)//如果是最后一块蛋糕了,那么sum不需要清零了break;sum = 0;}}if (sum < k)//如果蛋糕分完了还是不够knum++;printf("%d",num);return 0;
}

学生排队


一道逻辑题:

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 1010;
struct student {int id;int weizhi;
}stu[maxn];
bool cmp(student a, student b)
{return a.weizhi < b.weizhi;
}
int main() {int n,m;scanf("%d%d",&n,&m);int i,j;int temp1, temp2;int flag = 0;for (i = 1; i <= n; i++){stu[i].id = i;stu[i].weizhi = i;}for (j = 1; j <= m; j++){sort(stu + 1, stu + n + 1, cmp);/*for (i = 1; i <= n; i++){printf("%d ", stu[i].id);}*/flag = 0;scanf("%d %d",&temp1,&temp2);if (temp2 == 0)//啥也不做;else if (temp2 < 0)//说明要向前移动{for (i = n; i >=1 && temp2 != 0; i--){if (flag == 1){stu[i].weizhi++;//printf("stu[%d].weizhi++,=%d\n", i, stu[i].weizhi);temp2++;}if (stu[i].id == temp1 && flag == 0){stu[i].weizhi += temp2;flag = 1;}}}else//向后移动{for (i = 1; i <= n&&temp2!=0; i++){               if (flag == 1){//printf("!!!\n");stu[i].weizhi--;//printf("stu[%d].weizhi--,=%d\n", i, stu[i].weizhi);temp2--;}if (stu[i].id == temp1&&flag==0){stu[i].weizhi += temp2;    flag = 1;}     }}      }sort(stu + 1, stu + n + 1, cmp);for (i = 1; i <= n; i++){printf("%d ", stu[i].id);}    return 0;
}

Markdown


这是一道经典的处理字符串的题目
这里对string的处理很厉害,多多参考

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <map>
#include<string>
/* CCF201703-3 Markdown */
using namespace std;
string line, text;
// 段落处理
void solve()//从行内处理到标题和无序列表,最后在前后加上<p>
{// 处理下划线:标签<em></em>/** 这里注意成对的替换,可以用leftp和rightp来表示位置*/int leftp = text.find("_");while (leftp != string::npos) {text.replace(leftp, 1, "<em>");int rightp = text.find("_", leftp);text.replace(rightp, 1, "</em>");leftp = text.find("_", rightp);}// 处理方括号/** 注意这里取子字符串的手法,妙* 在replace的时候把这个子串给全部替换了*/leftp = text.find("[");while (leftp != string::npos) {int rightp = text.find("]", leftp);int leftp2 = text.find("(", rightp);int rightp2 = text.find(")", leftp2);string tmp = text.substr(leftp + 1, rightp - leftp - 1);string tmp2 = text.substr(leftp2 + 1, rightp2 - leftp2 - 1);text.replace(text.begin() + leftp, text.begin() + rightp2 + 1, "<a href=\"" + tmp2 + "\">" + tmp + "</a>");leftp = text.find("[", rightp2);}if (text[0] == '#') {// 处理#:标签<h></h>int i = 0;while (text[i] == '#') i++;//i是字符#的个数//这里的string(num,'c')生成一个字符串,包含num和c字符text = "<h" + string(1, '0' + i) + ">" + text.substr(i + 1);//这里题目说的是一个或者多个空格,其实只有1个空格text.insert(text.size() - 1, "</h" + string(1, '0' + i) + ">");//在string的末尾加上多的字符串}else if (text[0] == '*') {// 处理*:标签<ul><li></li>......</ul>text.insert(0, "<ul>\n");text.insert(text.size(), "</ul>\n");int leftp = text.find("*");while (leftp != string::npos) {int rightp = text.find("\n", leftp);text.insert(rightp, "</li>");text.replace(leftp, 2, "<li>");leftp = text.find("*", rightp);}}else {// 处理段落:<p></p>text = "<p>" + text.substr(0, text.size() - 1) + "</p>\n";}cout << text;text = "";
}
/*
* 1.这题是经典的字符串处理的题目,注意区块的处理,因为每个区块之间的处理不相干
* 所以处理完一个text区块之后就可以直接输出,然后将text清零
*/
int main()//注意这里的输入很重要!
{bool flag = false;getline(cin, line);for (; ;) {if (line.size() > 0)text += line + "\n";else if (line.size() == 0 && text.size() > 0)solve();if (flag) break;//如果找不到Line的输入了,就让flag=1然后在下次循环的时候直接退出if (!getline(cin, line)) {flag = true;line = "";}}return 0;
}

地铁修建

最短路:答案为所有可能的线路中用时最短的一个,而所用最少天数取决于一条线路中所需修建时间最长的一条隧道,所以这是一个在最大值中找最小值的问题。跑一遍dijkstra或者spfa,对于一条边u->v,更新dis[v]时,先比较前驱的最短路径dis[u]与u->v的权值,取较大者为tmpdis,再将tmpdis与dis[v]比较,令dis[v]取较小者,就完成了更新。

需要注意的是,最短路的做法需要关同步,否则会超时;最小生成树不需要关同步。

下面是dijkstra的代码:

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+10;
const int maxm = 2e5+10;
struct node
{int x, d;node() {}node(int X, int D): x(X), d(D) {}bool operator < (const node& a) const{if(d == a.d)return x < a.x;return d > a.d;}
};
int n, m;
int dis[maxn];
vector <node> r[maxn];void read()
{cin >> n >> m;for(int i = 0; i < m; ++i){int u, v, w;cin >> u >> v >> w;r[u].push_back(node(v, w));r[v].push_back(node(u, w));}
}void dijkstra(int s)
{for(int i = 2; i <= n; ++i)dis[i] = INF;dis[1] = 0;int vis[maxn] = {0};priority_queue <node> q;q.push(node(s, dis[s]));while(!q.empty()){node cur = q.top();q.pop();if(vis[cur.x])continue;for(int i = 0; i < r[cur.x].size(); ++i){node next = r[cur.x][i];int tmpdis = max(dis[cur.x], next.d);dis[next.x] = min(tmpdis, dis[next.x]);q.push(node(next.x, dis[next.x]));}vis[cur.x] = 1;}
}
void solve()
{dijkstra(1);cout << dis[n];
}int main()
{ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);read();solve();return 0;
}

最小生成树+并查集做法。由于同时开工,所以题意可理解为求最小生成树中的最大边权。于是,可以将所有边按权值升序排序,利用Kruskal算法,依次对边的两点进行并查集的合并操作,直到节点1与节点n同根,即起点与终点连通时,当前正在操作的边的权值即为答案。

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+10;
const int maxm = 2e5+10;
struct Edge
{int u, v, w;bool operator < (const Edge& e) const{return w < e.w;}
}edge[maxm];
int n, m;
int p[maxn];void read()
{cin >> n >> m;for(int i = 0; i < m; ++i)cin >> edge[i].u >> edge[i].v >> edge[i].w;
}int find(int x)
{int r = x;while(p[r] != r)r = p[r];int i = x, j;while(i != r) //路径压缩{j = p[i];p[i] = r;i = j;}return r;
}void Union(int x, int y)
{int rx = find(x), ry = find(y);if(rx != ry)p[rx] = p[ry];
}void solve()
{sort(edge, edge+m);for(int i = 0; i <= n; ++i)p[i] = i;for(int i = 0; i < m; ++i){Union(edge[i].u, edge[i].v);if(find(1) == find(n)) //1与n同根,则连通{cout << edge[i].w;break;}}
}int main()
{read();solve();return 0;
}

引水入城

2017-09

打酱油

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
int main() {int n;scanf("%d",&n);int sum = 0;if (n >= 50)sum += n / 50 * 7;n = n - n / 50 * 50;if (n >= 30)sum += n / 30 * 4;n = n - n / 30 * 30;sum += n / 10;printf("%d",sum);return 0;
}

公共钥匙盒


同样是结构体+逻辑,涉及排序
一开始我想要定老师为一个结构体,后来发现应该把取钥匙或者还钥匙的操作定义为一个结构体
1、当换完钥匙之后立即break
2、注意结构体排序函数cmp的编写

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 2010;
struct yaoshi {int id;//钥匙的编号int time;//借或者还的时间int flag;//表示是换钥匙还是取钥匙,flag=-1表示取钥匙,flag=1表示还钥匙
}Yao[maxn];
bool cmp(yaoshi a, yaoshi b)
{   if (a.time != b.time)//首先按照时间顺序排序return a.time < b.time;else if (a.flag != b.flag) return a.flag > b.flag;//如果时间相同,就先换钥匙,再取钥匙else//如果还的时间相同,就按照id大小还钥匙return a.id < b.id;
}
int main() {int n,k;int i;int j;int id;int a[maxn] = {0};//0表示没有钥匙在上面,n表示n号钥匙在上面scanf("%d %d",&n,&k);//初始化钥匙盒for (i = 1; i <= n; i++){a[i] = i;}//初始化钥匙,并排序for (i = 1; i <=2*k; i+=2)//一共2k个操作{scanf("%d",&id);scanf("%d %d", &Yao[i].time, &Yao[i+1].time);Yao[i].id = Yao[i+1].id = id;Yao[i + 1].time += Yao[i].time;Yao[i].flag = -1;//取钥匙Yao[i+1].flag = 1;//还钥匙}    sort(Yao+1, Yao + 2*k+1, cmp);for (i = 1; i <=2*k; i++)//遍历2*k次钥匙操作{if (Yao[i].flag == -1)//如果是取钥匙{for (j = 1; j <= n; j++)if (a[j] == Yao[i].id){a[j] = 0;break;}                    }else//还钥匙{for (j = 1; j <= n; j++)if (a[j] == 0){a[j] = Yao[i].id;//这里注意还完钥匙,不用再寻找后面空的钥匙位了break;}                 }   }for (j = 1; j <= n; j++)printf("%d ", a[j]);return 0;
}

JSON查询

#define _CRT_SECURE_NO_WARNINGS 1
#include<string>
#include <iostream>
#include <string>
#include <map>
using namespace std;
/*
* 1.在读取字符串时选择将一整个字符串逐行读入s中,s中保留了所有字符串
* 2.在读入数据后记得getline()或者getchar()读入换行符
* 3.因为题目中既有匹配关系,又有嵌套关系,所以用ans保留匹配的值,用stf来保留继承关系
*/
//ans保存键和值,stf保存继承关系(strfather)
map<string, string> ans, stf;
//提取字符串
string get(int& i, string str)
{string s;while (str[++i] && str[i] != '"')//从str[1]开始计算{if (str[i] == '\\')//说明如果出现了斜杠,直接跳过s += str[++i];elses += str[i];}return s;
}
int main()
{int n, m;string s, str, name, key, val;(cin >> n >> m).get();//注意读取换行符,否则影响之后的处理!while (n--){getline(cin, s);str += s;}//得到了最终的一长串strfor (int i = 1; i < str.size() - 1; ++i){if (str[i] == ' ' || str[i] == ',')continue;else if (str[i] == '"')key = get(i, str);//获取键else if (str[i] == ':'){while (str[++i] == ' ');//跳过空格if (str[i] == '"')//获取值{val = get(i, str);ans[name + '.' + key] = val;}else if (str[i] == '{')//继承关系的转换{ans[name + '.' + key] = "OBJECT";stf[name + '.' + key] = name;//保存父代键值,之后回退name += ('.' + key);//子代键前缀名}}else if (str[i] == '}')name = stf[name];//回退到父代}while (m--){cin >> s;s = '.' + s;if (ans[s] == "")cout << "NOTEXIST" << endl;else if (ans[s] == "OBJECT")cout << ans[s] << endl;elsecout << "STRING " << ans[s] << endl;}//   system("pause");return 0;
}

通信网络

混分25

#define _CRT_SECURE_NO_WARNINGS 1
#include<string>
#include <iostream>
#include <string>
#include <map>
#include<vector>
#include<queue>
using namespace std;
//思路F算法求多源最短路径
const int INF = 1000000000;
const int maxn = 1010;
int n, m;
vector<int> dis[maxn];//记录每个元素可以到达的路径
vector<int> Adj[maxn];//表示邻接表
int ans[maxn][maxn] = {0};//总共有多少个点可以到达bool inq[maxn] = {0};//表示是否进入过这个点int main()
{scanf("%d %d",&n,&m);int u, v;for (int i = 0; i < m; i++){scanf("%d %d",&u,&v);Adj[u].push_back(v);//u->v}for (int i = 1; i <= n; i++){for (int j = 0; j < Adj[i].size(); j++){v = Adj[i][j];ans[i][v]=1;//i->vfor (int k1 = 1; k1 <= n; k1++){if (ans[v][k1] == 1)ans[i][k1] = 1;if (ans[k1][i] == 1)ans[k1][v] = 1;              }           }}for (int i = 1; i <= n; i++){for (int j = 0; j < Adj[i].size(); j++){v = Adj[i][j];ans[i][v] = 1;//i->vfor (int k1 = 1; k1 <= n; k1++){if (ans[v][k1] == 1)ans[i][k1] = 1;if (ans[k1][i] == 1)ans[k1][v] = 1;}}}//for (int i = 1; i <= n; i++)//{// for (int j = 1; j <= n; j++)//   {//     printf("%d ",ans[i][j]);//    }// printf("\n");//}int flag;int sum = 0;for (int i = 1; i <= n; i++){flag = 1;for (int j = 1; j <= n; j++){if (j == i)continue;if (ans[i][j] == 0){flag = 0;break;}}sum += flag;flag = 1;for (int j = 1; j <= n; j++){if (j == i)continue;if (ans[j][i] == 0){flag = 0;break;}}sum += flag;}printf("%d\n",sum);return 0;
}

图的DFS遍历

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e3+24;
int n, m, ans = 0;
bool r[maxn][maxn], vis[maxn];
vector <int> e[maxn];void read()
{cin >> n >> m;for(int i = 0; i < m; ++i){int u, v;cin >> u >> v;e[u].push_back(v);}
}void dfs(int u, int v) //u为当前查找的点,v为直接或间接与u相连通的点
{r[u][v] = true; //u可以访问到vr[v][u] = true; //v可以访问到uvis[v] = true;for(int i = 0; i < e[v].size(); ++i)if(!vis[e[v][i]])dfs(u, e[v][i]);
}void solve()
{for(int i = 1; i <= n; ++i){memset(vis, 0, sizeof(vis));dfs(i, i); //搜索每个点,从自身开始查找}for(int i = 1; i <= n; ++i){int cnt = 0;for(int j = 1; j <= n; ++j)if(r[i][j])cnt++;if(cnt == n)ans++;}cout << ans;
}int main()
{read();solve();return 0;
}

Floyd求距离也可以

除法

2017-12

最小差值

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
int a[1010] = { 0 };
int main() {int n;int min;int i;int temp;scanf("%d", &n);for (i = 0; i < n; i++){scanf("%d", &a[i]);}sort(a, a + n);min = a[1] - a[0];for (i = 1; i < n-1; i++){temp = a[i + 1] - a[i];if (temp < min)swap(temp, min);}printf("%d",min);return 0;
}

游戏

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
#include<limits>
using namespace std;
int n;
int k;
const int maxn = 1010;
int hashtable[maxn];
int judge(int num)//输入小朋友们报的数,返回1说明被淘汰,返回0说明不被淘汰
{if (num % 10 == k)//末位是kreturn 1;else if (num % k == 0)//k的倍数return 1;else return 0;
}
int main()
{scanf("%d %d",&n,&k);for (int i = 1; i <= n; i++){hashtable[i] = 1;//首先初始化都存活}int num = n;//当前存活个数int temp=0;//当前报的数while (num > 1){for (int i = 1; i <= n; i++){if (hashtable[i] == 1){temp++;//cout << "当前到小朋友" << i << "报数" << temp << endl;if (judge(temp))//如果要被淘汰{//cout << "被淘汰" << endl;hashtable[i] = 0;num--;if (num == 1)break;}}}}    for (int i = 1; i <= n; i++){if (hashtable[i] == 1){printf("%d\n",i);break;}}return 0;
}

Crontab


样例跑通的代码,得了5分。。

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
//Crontab
long long int time1, time2;
int n;
const int maxn = 25;
struct Crontab
{string minutes;string hours;string dayOfMonth;string month;string dayOfWeek;string zhiling;vector<int> min;vector<int> hou;vector<int> dayOfM;vector<int> mon;//先判断有效时间,如果合法再判断星期是否合法vector<long long int> times;//有效时间vector<int> dayOfW;}crontab[maxn];
int Mon[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31} };
string Month[13] = { "","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
string Week[7] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
int computeday(int days,int month,int year)
{//判断days在month里面有没有超时int flag=0;if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//是闰年flag = 1;if (days <= Mon[flag][month])return 0;elsereturn 1;}
int runyear(int year)//闰年返回1,非闰年返回0
{if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//是闰年return 1;else return 0;
}
int judge2(int id,long long year,long long month,long long day)//判断time是否是crontab[id]里面允许的星期,time为年月日
{int num;//num表示time的星期int sum=0;//表示过去的总天数for (int i = 1970; i <= year - 1; i++){sum += 365;if (runyear(i))//如果是闰年,额外加1sum += 1;}   int flag = runyear(year);//当年是不是闰年for (int i = 1; i <= month-1; i++)sum += Mon[flag][i];//加上月份的时间sum += day;//加上天数sum += 3;sum %= 7;//当天是星期sum//cout << "是星期" << sum << endl;//查看sum是否在crontab[id]里面flag = 0;for (int i = 0; i < crontab[id].dayOfW.size(); i++){if (crontab[id].dayOfW[i] == sum){flag = 1; break;}}return flag;}
void judge(int year,long long time,long long month,long long day)//函数功能:判断time是否合法,如果合法,就输出对应的指令
{int flag=0;for (int i = 0; i < n; i++){for (int j = 0; j < crontab[i].times.size(); j++){if (crontab[i].times[j] == time)//时间合适并且星期合适{//cout << time<<"日期合适" << endl;if (judge2(i, year, month, day)){//cout << "星期合适" << endl;flag = 1;cout << year << time << " " << crontab[i].zhiling << endl;break;}}}if (flag == 1)break;            }
}
void func(int id, string s, vector<int>& vi)
{int num1, num2;int p;num1 = 0; num2 = 0; p = 1;for (int i = 0; i < s.length(); i++){if (s[i] == ','){if (num2 == 0)vi.push_back(num1);//else//输入0-2;{for (int j = num1; j <= num2; j++){vi.push_back(j);}}//上面结束了num1 = num2 = 0; p = 1;}else if (s[i] == '-'){i++;p = 1;num2 = num2 * p + (s[i] - '0');p *= 10;}else{num1 = num1 * p + (s[i] - '0');p *= 10;}}if (num2 == 0)vi.push_back(num1);//else//输入0-2;{for (int j = num1; j <= num2; j++){vi.push_back(j);}}}
void handle(int id)//处理crontab[id]
{//1.处理minif (crontab[id].minutes.find("*") != -1)//如果有*{for (int i = 0; i <= 59; i++)crontab[id].min.push_back(i);}else//如果没有*,那么遍历{func(id, crontab[id].minutes, crontab[id].min);}//2.处理hoursif (crontab[id].hours.find("*") != -1){for (int i = 0; i <= 23; i++)crontab[id].hou.push_back(i);}else{func(id, crontab[id].hours, crontab[id].hou);}//3.处理dayOfMonthif (crontab[id].dayOfMonth.find("*") != -1){for (int i = 1; i <= 31; i++)crontab[id].dayOfM.push_back(i);}else{func(id, crontab[id].dayOfMonth, crontab[id].dayOfM);}//4.处理monthif (crontab[id].month.find("*") != -1){for (int i = 1; i <= 12; i++)crontab[id].mon.push_back(i);}else{func(id, crontab[id].month, crontab[id].mon);}if (crontab[id].dayOfWeek.find("*") != -1){for (int i = 0; i <= 6; i++)crontab[id].dayOfW.push_back(i);}else{func(id, crontab[id].dayOfWeek, crontab[id].dayOfW);}}
//函数功能,将字符转换为数字
void charToint(int id)
{int pos;char str[10];//1.改monthfor (int i = 1; i <= 12; i++){pos = crontab[id].month.find(Month[i]);if (pos != -1)//替换成i表示的char{_itoa(i, str, 10);crontab[id].month.replace(pos, 3, str);}}//2.改dayofweekfor (int i = 0; i <= 6; i++){pos = crontab[id].dayOfWeek.find(Week[i]);if (pos != -1)//替换成i表示的char{//cout << "找到了"<<Month[i] << endl;_itoa(i, str, 10);crontab[id].dayOfWeek.replace(pos, 3, str);}}}
int main()
{scanf("%d", &n);scanf("%lld %lld", &time1, &time2);for (int i = 0; i < n; i++){cin >> crontab[i].minutes >> crontab[i].hours >> crontab[i].dayOfMonth >> crontab[i].month >> crontab[i].dayOfWeek >> crontab[i].zhiling;//五个输入crontab[i].min.clear(); crontab[i].hou.clear(); crontab[i].dayOfM.clear(); crontab[i].mon.clear(); crontab[i].dayOfW.clear();//初始化charToint(i);//将month和dayOfWeek的字符变成数字handle(i);crontab[i].times.clear();//处理完成后for (int j1 = 0; j1 < crontab[i].mon.size(); j1++){long long int days = 0;for (int j2 = 0; j2 < crontab[i].dayOfM.size(); j2++){for (int j3 = 0; j3 < crontab[i].hou.size(); j3++){for (int j4 = 0; j4 < crontab[i].min.size(); j4++){days = crontab[i].mon[j1] * 1000000 + crontab[i].dayOfM[j2] * 10000 + crontab[i].hou[j3] * 100 + crontab[i].min[j4];//cout <<"days="<< days << endl;crontab[i].times.push_back(days);}}}}}int flag;long long temp;//下面判断输出,循环时间long long t1, t2, t3, t4, t5;long long time;//表示当前的时间t1 = time1 % 100; time1 /= 100;//分钟t2 = time1 % 100; time1 /= 100;//小时t3 = time1 % 100; time1 /= 100;//日期t4 = time1 % 100; time1 /= 100;//月份t5 = time1;//年份do{time =t4 * 1000000 + t3 * 10000 + t2 * 100 + t1;//cout << "time=" << time << " time2=" << time2 << endl;judge(t5,time,t4,t3);t1++;if (t1 == 60)t2++,t1 = 0;if (t2 == 24)t3++, t2 = 0;if (computeday(t3, t4, t5))//如果日期超了t4++, t3 = 1;if (t4 == 13)t5++, t4 = 1;//cout <<t5<< t4 << t3 << t2 << t1 << endl;time = t5 * 100000000+ t4 * 1000000 + t3 * 10000 + t2 * 100 + t1;//cout << "time=" << time << " time2=" << time2 << endl;} while (time != time2);//留下后面的时间//调试输出/*for (int i = 0; i < n; i++){cout << "当前是第" << i + 1 << "个" << endl;cout << "分钟:";for (int j = 0; j < crontab[i].min.size(); j++){cout << crontab[i].min[j] << " ";}cout << endl;cout << "小时:";for (int j = 0; j < crontab[i].hou.size(); j++){cout << crontab[i].hou[j] << " ";}cout << endl;cout << "dayOfM:";for (int j = 0; j < crontab[i].dayOfM.size(); j++){cout << crontab[i].dayOfM[j] << " ";}cout << endl;cout << "mon:";for (int j = 0; j < crontab[i].mon.size(); j++){cout << crontab[i].mon[j] << " ";}cout << endl;cout << "dayOfW:";for (int j = 0; j < crontab[i].dayOfW.size(); j++){cout << crontab[i].dayOfW[j] << " ";}cout << endl;//cout << "当前的times";//for (int j = 0; j < crontab[i].times.size(); j++)//{// cout << crontab[i].times[j] << endl;//}}*/return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
/* CCF201712-3 Crontab */
#include <iostream>
#include <vector>
#include <queue>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>using namespace std;const char* weeks_months[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
const int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int leapyear(int year, int month)
{if (month == 2)return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? 1 : 0;elsereturn 0;
}// Crontab
const int V = 5;
vector<pair<int, int> > v[V];   // 分别表示:分钟,小时,日,月份,星期
string cmd;struct CMD {int id;long long time;string cmd;bool operator < (const CMD& a) const //要按时间和先后顺序排好{return (time == a.time) ? id > a.id : time > a.time;}
};char buf[256];int getval(char t[])
{int i;t[0] = toupper(t[0]);for (i = 1; t[i]; i++)t[i] = tolower(t[i]);for (i = 0; i < 12 + 7; i++)if (strcmp(t, weeks_months[i]) == 0)break;if (i < 12 + 7)return i < 7 ? i : i - 6;elsereturn -1;
}void setsubval(char s[], vector<pair<int, int> >& v)
{int p1 = 0, p2 = 0;for (int i = 0; s[i]; i++)if (s[i] == '-') {s[i] = '\0';p2 = i + 1;break;}int val1, val2;if (p1 == p2) {if (isdigit(s[0]))val1 = atoi(s);elseval1 = getval(s);v.push_back(make_pair(val1, val1));}else {if (isdigit(s[0]))val1 = atoi(s);elseval1 = getval(s);if (isdigit(s[p2]))val2 = atoi(s + p2);elseval2 = getval(s + p2);v.push_back(make_pair(val1, val2));}
}
//数组和pair<int,int>
void setval(char s[], vector<pair<int, int> >& v)
{if (s[0] == '*')v.push_back(make_pair(-1, -1));else {char* p = strtok(s, ",");while (p) {setsubval(p, v);p = strtok(NULL, ",");}}
}int myatoi(char t[], int b, int e)
{int v = 0;for (int i = b; i <= e; i++)v = v * 10 + t[i] - '0';return v;
}bool judge(int m, vector<pair<int, int> >& v)
{for (int i = 0; i < (int)v.size(); i++)if (v[i].first == -1 || (v[i].first <= m && m <= v[i].second))return true;return false;
}bool end_time_check(int y, int m, int d, int h, int mi, int ey, int em, int ed, int eh, int emi)
{if (y < ey) return true;if (m > em) return false;if (m < em) return true;if (d > ed) return false;if (d < ed) return true;if (h > eh) return false;if (h < eh) return true;if (mi > emi) return false;if (mi < emi) return true;return false;
}// 适用于1582年10月15日之后, 因为罗马教皇格里高利十三世在这一天启用新历法
// 蔡勒公式:给定年月日,得到当天是星期几
int weekday(int year, int month, int day)
{if (month == 1 || month == 2) {month += 12;year--;}int c = year / 100;int y = year % 100;int m = month;int d = day;int w = c / 4 - 2 * c + y + y / 4 + 26 * (m + 1) / 10 + d - 1;if (w < 0)return (w + (-w / 7 + 1) * 7) % 7;return w % 7;
}int main()
{int n;string s, t;priority_queue<CMD> q;cin >> n >> s >> t;//将字符串转换为数组存如buf中//分别存储开始和结束的年月日时分strcpy(buf, s.c_str());int sy = myatoi(buf, 0, 3);int sm = myatoi(buf, 4, 5);int sd = myatoi(buf, 6, 7);int sh = myatoi(buf, 8, 9);int smi = myatoi(buf, 10, 11);strcpy(buf, t.c_str());int ey = myatoi(buf, 0, 3);int em = myatoi(buf, 4, 5);int ed = myatoi(buf, 6, 7);int eh = myatoi(buf, 8, 9);int emi = myatoi(buf, 10, 11);for (int i = 0; i < n; i++) {string ss;// 分别处理:分钟,小时,日,月份,星期for (int j = 0; j < V; j++) {v[j].clear();cin >> ss;//输入字符串strcpy(buf, ss.c_str());setval(buf, v[j]);}// Commandcin >> cmd;int k = sm, l = sd, m = sh, n = smi;    // 分别作为月份、日、小时和分钟的循环变量for (int j = sy; j <= ey; j++, k = 1)  // 年循环处理for (; k <= 12; k++, l = 1)if (judge(k, v[3]))for (; l <= days[k] + leapyear(j, k); l++, m = 0)if (judge(l, v[2]) && judge(weekday(j, k, l), v[4]))for (; m < 24; m++, n = 0)if (judge(m, v[1]))for (; n < 60; n++) {if (!end_time_check(j, k, l, m, n, ey, em, ed, eh, emi))break;if (judge(n, v[0])) {CMD tmp;tmp.id = i;tmp.time = (long long)j * 100000000 + (long long)k * 1000000 + (long long)l * 10000 + (long long)m * 100 + n;tmp.cmd = cmd;q.push(tmp);}}}while (!q.empty()) {CMD tmp = q.top();q.pop();cout << tmp.time << " " << tmp.cmd << endl;}return 0;
}

行车路线

裸DJ算法80分

#include <iostream>
#include <cstring>
using namespace std;const long long inf = 1e14;
long long edge[505][505];   //边的长度
bool vis[505];              //是否已经确定最短路径的长度
long long d[505];           //最短路径的长度
long long cur,a,b,c,n,m,flag,imin;void init()
{memset(edge,0,sizeof(edge));memset(vis,0,sizeof(vis));for(int i=1; i<=n; ++i)d[i] = inf;vis[1] = cur = 1;d[1] = 0;for(int i=0; i<m; ++i)  //处理各边长度 {cin>>flag>>a>>b>>c;if(flag == 1) c *= c;if(edge[a][b]==0 || c < edge[a][b])edge[a][b] = edge[b][a] = c;}
}int main()
{cin>>n>>m;init();for(int i=1; i<=n-1; ++i) //要再次加入n-1个结点 {for(int j=1; j<=n; ++j) //松弛当前结点的每一条出边 {if(vis[j]==0 && edge[cur][j] && edge[cur][j] + d[cur] < d[j])d[j] = edge[cur][j] + d[cur];}imin = inf;for(int j=1; j<=n; ++j)  //找到d值最小的结点 {if(vis[j]==0 && imin > d[j]){imin = d[j];cur = j;}}vis[cur] = 1;if(cur==n) break; //结点n的最短路径被找到,退出 }cout<<d[n];return 0;
}

商路

2018-03

跳一跳


小模拟

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<queue>
#include<stack>
#include<map>
using namespace std;
int n;
int sum;
int score;
int main()
{sum = 0;while (scanf("%d", &n) != EOF){if (n == 0)break;else{if (n == 1)score = 1;else{if (score == 1)score = 2;elsescore += 2;}sum += score;}}printf("%d\n",sum);return 0;
}

碰撞的小球


注意最后输出要按照id排序

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
const int maxn = 110;//最多小球数量
struct Ball {int loc;//小球的位置int flag;//flag=1表示向右运动,=-1表示向左运动int id;
}ball[maxn];
int n;//小球数量
int L;//线段长度
int t;//时间
bool cmp(Ball a, Ball b)
{if (a.loc != b.loc) return a.loc < b.loc;else if (a.flag != b.flag) return a.flag < b.flag;else return 1;
}
bool cmp1(Ball a, Ball b)
{return a.id < b.id;
}
int main()
{scanf("%d %d %d", &n, &L, &t);for (int i = 0; i < n; i++) {scanf("%d",&ball[i].loc);ball[i].flag = 1;ball[i].id = i;}//将小球按照位置排序;//下面模拟t秒for (int i = 1; i <= t; i++){for (int j = 0; j < n; j++){ball[j].loc += ball[j].flag;}//按照位置和flag排序sort(ball, ball + n, cmp);if (ball[n - 1].loc == L)ball[n - 1].flag = -1;//向左for (int j = 0; j < n - 1; j++){//首先将撞墙的flag调回来if (ball[j].loc == L){ball[j].flag = -1;}if (ball[j].loc == 0){ball[j].flag = 1;}if (ball[j].loc == ball[j + 1].loc && ball[j].flag != ball[j + 1].flag)//loc相同,flag不同{ball[j].flag = 0 - ball[j].flag;ball[j + 1].flag = 0 - ball[j + 1].flag;//如果撞到了就换方向}}}//按照id重新排序sort(ball, ball + n, cmp1);for (int i = 0; i < n; i++){printf("%d ", ball[i].loc);}return 0;
}

URL映射


经典的字符串处理

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
const int maxn = 110;
struct R {string p;string r;
}rule[maxn];
string str1, str2;
string lstr, rstr, str;
vector<string> canshu;//保存参数
vector<int> canshuflag;
int n, m;
int pos;
int pos1;
int lpos, rpos;
int flag;
int func(char c)//合法返回1,否则返回0
{if (c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '-' || c == '_' || c == '.' || c == '/')return 1;elsereturn 0;
}
int judge(int id, string fastr, string sonstr)//父串与子串
{int ff = 0;//表示最后有没有加///如果最后没有/,加上/if (fastr[fastr.length() - 1] != '/'){fastr += "/";}if (sonstr[sonstr.length() - 1] != '/'){ff = 1;sonstr += "/";}canshu.clear();//清楚所有参数    canshuflag.clear();//清楚flgaint fapos, sonpos;string fa, son;while (fastr.length() != 0 && sonstr.length() != 0)//父串不为0时{fapos = fastr.find("/");sonpos = sonstr.find("/");fa = fastr.substr(0, fapos);son = sonstr.substr(0, sonpos);//cout << "fapos=" << fapos << " " << "sonpos=" << sonpos << endl;//cout << "fastr=" << fastr << " " << "sonstr=" << sonstr << endl;//cout << "fa=" << fa << " " << "son=" << son << endl;if (fa == "<int>"){for (int i = 0; i < son.length()-1; i++){if (son[i] > '9' || son[i] < '0')//如果不是数字{//printf("!!");return 0;}}canshu.push_back(son);canshuflag.push_back(1);//数字}else if (fa == "<str>"){canshu.push_back(son);canshuflag.push_back(0);}else if (fa == "<path>")//说明到最后了{if (ff == 1)sonstr.erase(sonstr.length() - 1, 1);canshu.push_back(sonstr);canshuflag.push_back(0);fastr = "";sonstr = "";break;}else//直接匹配{if (fa != son){return 0;}}fastr = fastr.substr(fapos + 1);sonstr = sonstr.substr(sonpos + 1);}if (fastr.length() != 0 || sonstr.length() != 0)//说明没有匹配完return 0;else{cout << rule[id].r;for (int i = 0; i< canshu.size(); i++){if (canshuflag[i] == 0)//字符直接输出;else//数字{int j;for (j = 0; j < canshu[i].size(); j++){if (canshu[i][j] != '0')break;}canshu[i] = canshu[i].substr(j);}cout << " " << canshu[i];}cout << endl;return 1;}
}
int main()
{scanf("%d %d", &n, &m);getchar();for (int i = 0; i < n; i++){cin >> str1 >> str2;rule[i].p = str1;rule[i].r = str2;}for (int i = 0; i < m; i++)//m条查询{flag = 0;//若匹配成功,flag=1    int flag1 = 1;cin >> str;for (int j = 0; j < str.length(); j++){if (func(str[j]) == 0){flag1 = 0;break;}}if (flag1 == 1){for (int j = 0; j < n; j++){string fastr = rule[j].p;string sonstr = str;if (judge(j, fastr, sonstr))//返回1说明合法{flag = 1;break;}else//说明不合法.继续找{continue;}}if (flag == 0)cout << "404" << endl;}}return 0;
}

棋局评估

不太懂这个算法

#define _CRT_SECURE_NO_WARNINGS 1
/* CCF201712-3 Crontab */
#include <iostream>
#include <vector>
#include <queue>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
int mp[5][5];
int solve(int p) {int num = 0;rep(i, 1, 3) {rep(j, 1, 3) {if (!mp[i][j])num++;}}if (p == 1)return num + 1;else return -num - 1;
}
int check() {int num1 = 0, num2 = 0, p = 0;rep(i, 1, 3) {num1 = 0, num2 = 0;rep(j, 1, 3) {if (mp[i][j] == 1)num1++;if (mp[i][j] == 2)num2++;}if (num1 == 3) {p = 1;break;}if (num2 == 3) {p = 2;break;}}if (p)return solve(p);rep(j, 1, 3) {num1 = 0, num2 = 0;rep(i, 1, 3) {if (mp[i][j] == 1)num1++;if (mp[i][j] == 2)num2++;}if (num1 == 3) {p = 1;break;}if (num2 == 3) {p = 2;break;}}if (p)return solve(p);num1 = 0, num2 = 0;rep(i, 1, 3) {if (mp[i][i] == 1)num1++;if (mp[i][i] == 2)num2++;}if (num1 == 3)return solve(1);if (num2 == 3)return solve(2);num1 = 0, num2 = 0;rep(i, 1, 3) {if (mp[i][4 - i] == 1)num1++;if (mp[i][4 - i] == 2)num2++;}if (num1 == 3)return solve(1);if (num2 == 3)return solve(2);int flag = 0;rep(i, 1, 3) {rep(j, 1, 3) {if (!mp[i][j]) {flag = 1;break;}}if (flag)break;}if (!flag)return 0;return 1e9;
}
int dfs(int num) {int rst;if (num == 1)rst = -1e9;else rst = 1e9;int flag = check();if (flag != 1e9)return flag;rep(i, 1, 3) {rep(j, 1, 3) {if (mp[i][j] == 0) {mp[i][j] = num;if (num == 1)rst = max(rst, dfs(2));else rst = min(rst, dfs(1));mp[i][j] = 0;}}}return rst;
}
int main()
{int t;scanf("%d", &t);while (t--) {rep(i, 1, 3) {rep(j, 1, 3) {scanf("%d", &mp[i][j]);}}int ans = dfs(1);printf("%d\n", ans);}return 0;
}

二次求和

2018-09

卖菜

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 1010;
int shop1[maxn] = { 0 };
int shop2[maxn] = { 0 };
int main() {int n;scanf("%d",&n);int i;for (i = 0; i < n; i++){scanf("%d",&shop1[i]);}for (i = 1; i < n - 1; i++){shop2[i] = (shop1[i - 1] + shop1[i] + shop1[i + 1])/3;}shop2[0] = (shop1[0] + shop1[1]) / 2;shop2[n-1]= (shop1[n-1] + shop1[n-2]) / 2;for (i = 0; i < n; i++){printf("%d ",shop2[i]);}return 0;
}

买菜

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 1000010;
struct hash {int id;int biaoji;
}hashtable[maxn];
int main() {int n;scanf("%d",&n);int i,j;int temp1, temp2;int sum=0;//首先初始化for (i = 0; i < n; i++){hashtable[i].id = hashtable[i].biaoji = 0;}for (i = 1; i <=n; i++){scanf("%d %d",&temp1,&temp2);for (j = temp1; j <= temp2; j++){hashtable[j].id = 1;hashtable[j].biaoji = i;//同一个时间段的标记相同}}for (i = 1; i <= n; i++){scanf("%d %d", &temp1, &temp2);for (j = temp1; j < temp2; j++){if (hashtable[j].id == 1&&hashtable[j+1].id==1&&hashtable[j].biaoji==hashtable[j+1].biaoji)sum++;}}printf("%d",sum);return 0;
}

2018-12

小明上学

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
int r, y, g;
int n;
int k, t;
int sum;
int main()
{sum = 0;scanf("%d %d %d",&r,&y,&g);scanf("%d",&n);for (int i = 0; i < n; i++){scanf("%d %d",&k,&t);if (k == 0) sum += t;else if (k == 1){sum += t;}else if (k == 2){sum += r + t;//等完红灯等黄灯}else{;}}printf("%d\n",sum);return 0;
}

小明放学

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
long long r, y, g,t;
int n,k;
long long sum;
int main()
{sum = 0;long long time;scanf("%lld %lld %lld",&r,&y,&g);scanf("%d",&n);for (int i = 0; i < n; i++){scanf("%d %lld",&k,&t);if (k == 0) sum += t;//直接加上else if (k == 1)//出发时是红灯{if (sum <= t)//说明到达的时候还是红灯,还要再等t-sum+y秒{             sum = t;}          else//从红灯开始又走了sum-t秒{time = (sum - t) % (r + y + g);if (time <= g)//说明是{                 ;}else if (time <= y + g){sum += y + g - time + r;}else//还是红灯{sum += r + y + g - time;}}}else if (k == 2)//出发时是黄灯{if (sum <= t)//说明到达的时候还是黄灯,还要再等t-sum秒{             sum += t-sum+r;}             else//从黄灯开始又走了sum-t秒{time = (sum - t) % (r + y + g);if (time <= r){sum += r - time;}else if (time <=  g+r){;}else//还是黄灯//等完黄灯同行{sum += r + y + g - time+r;}}}else//出发时是绿灯{if (sum <= t)//说明到达的时候还是绿灯{;}              else{time = (sum - t) % (r + y + g);if (time <= y)//说明是红灯{sum += r - time + y;}else if (time <=  r+y)//说明是黄灯{sum += r + y - time;//等完红灯等黄灯}else//还是绿灯{                    ;}}}}printf("%lld\n",sum);return 0;
}

CIDR合并


做完第一步和第二步就可以得80分

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
//CIDR合并
string str;
const int maxn = 100010;
struct IP {int ip[4];int len;//长度int flag;//表示该ip地址是否有效string ipstr;//二进制的ip,一共有32位
}iplist[maxn];
int pos;
int pos1;
void handleip(int id, string str)
{pos = str.find("/");int num = 0;if (pos != -1)//标准型或者省略后缀型{iplist[id].len = stoi(str.substr(pos + 1), 0, 10);//首先确定长度str = str.substr(0, pos);}while (pos1 = str.find("."), pos1 != -1){iplist[id].ip[num] = stoi(str.substr(0, pos1), 0, 10);num++;str = str.substr(pos1 + 1);}iplist[id].ip[num] = stoi(str, 0, 10);//一共有num+1段if (pos == -1)//如果是省略长度型{iplist[id].len = 8 * (num + 1);}if (num < 3){num++;while (num <= 3){iplist[id].ip[num] = 0;num++;} while (num <= 3);}
}
void handleipstr(int id)
{//将id[0]-id[3]变成二进制加到ipstr后面//初始化iplist[id].ipstr = "";string tempstr;int tempnum;int num ;for (int i = 0; i <= 3; i++){tempstr = "";tempnum = iplist[id].ip[i];for (num = 1; num <= 8; num++){tempstr = to_string(tempnum % 2)+tempstr;tempnum /= 2;}iplist[id].ipstr += tempstr;}//cout << iplist[id].ipstr << endl;
}
bool cmp(IP a, IP b)
{if (a.ip[0] != b.ip[0]) return a.ip[0] < b.ip[0];else if (a.ip[1] != b.ip[1]) return a.ip[1] < b.ip[1];else if (a.ip[2] != b.ip[2]) return a.ip[2] < b.ip[2];else if (a.ip[3] != b.ip[3]) return a.ip[3] < b.ip[3];else return a.len <= b.len;//else return 1;
}
bool cmp1(IP a, IP b)
{return a.flag >= b.flag;
}
void judge(int id1, int id2)//功能:判断id2是不是id1的子集,如果是,就把id2的flag设置为0
{string str1, str2;//如果id1的长度小于id2.那么看id1的长度内两者是否相等,若相等,id2的flag变为0//如果id1的长度和id2一样,那么看两者的ip是否相等,若相等,id2的flag变为0str1 = iplist[id1].ipstr.substr(0, iplist[id1].len);str2 = iplist[id2].ipstr.substr(0, iplist[id1].len);if (str1 == str2)iplist[id2].flag = 0;
}
void merge(int id1,int id2)//同级合并
{;
}int main()
{int n;scanf("%d", &n);for (int i = 0; i < n; i++){//cout << "第" << i << "个" << endl;cin >> str;handleip(i, str);iplist[i].flag = 1;handleipstr(i);//printf("%d %d %d %d %d\n\n",iplist[i].ip[0], iplist[i].ip[1], iplist[i].ip[2], iplist[i].ip[3], iplist[i].len);}//1.第一步:排序//60sort(iplist, iplist + n, cmp);//2.第二步:从小到大合并//80for (int i = 0; i < n-1; i++){if (iplist[i].flag == 1){for (int j = i + 1; j < n; j++){if (iplist[j].flag == 1){judge(i,j);}}}}//3.第三步:统计合并/*for (int i = 0; i < n - 1; i++){if (iplist[i].flag == 1){for (int j = i + 1; j < n; j++){if (iplist[j].flag == 1){merge(i, j);}}}}*/for (int i = 0; i < n; i++){if(iplist[i].flag==1)//等于1才输出cout << iplist[i].ip[0] << "." << iplist[i].ip[1] << "." << iplist[i].ip[2] << "." << iplist[i].ip[3] << "/" << iplist[i].len << endl;}return 0;
}

数据中心


K算法求最小生成树,然后输出最大边

#include<iostream>
#include<algorithm>
using namespace std;
const int maxx=100010;
int n,m,root,tot,ans,father[maxx];
struct node
{int u;int v;int w;
}e[maxx];
int find(int x)
{if(x!=father[x])father[x]=find(father[x]);return father[x];
}
void unionn(int a,int b)
{int fa=find(a);int fb=find(b);father[fa]=fb;
}
bool cmp(const node &a,const node &b)
{return a.w<b.w;
}
int main()
{ans=-0x7f;cin>>n>>m>>root;for(int i=1;i<=m;i++)cin>>e[i].u>>e[i].v>>e[i].w;for(int i=1;i<=n;i++)father[i]=i;sort(e+1,e+m+1,cmp);for(int i=1;i<=m;i++){if(find(e[i].u)!=find(e[i].v)){unionn(e[i].u,e[i].v);ans=max(ans,e[i].w);tot++;}if(tot==n-1)break; }cout<<ans;return 0;
}

管道清洁


无汇源的最小费可行流
需要清洁的管道下界为1,不需要清洁的管道下界为0。
可重复经过的管道上界为正无穷,不可重复经过的管道上界为1。
然后建图直接跑最小费用流。

#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
const int maxn = 233;
const int inf = 0x3f3f3f3f;
struct node{int u,v,f,w,nxt;node(){};node(int a,int b,int c,int d,int e):u(a),v(b),f(c),w(d),nxt(e){}
}e[maxn*maxn];
int cnt = 0;
int head[maxn];
void add(int u,int v,int f,int w){e[cnt] = node(u,v,f,w,head[u]);head[u] = cnt++;e[cnt] = node(v,u,0,-w,head[v]);head[v] = cnt++;
}
int st,ed,E,ex;
int n,m;
int du[maxn];
int sum;
int num = 0;
void init(){scanf("%d%d",&n,&m);st = 0;ed = n + 1;ex = n + 2;cnt = 0;sum = 0;num = 0;memset(head,-1,ex<<2);memset(du,0,ex<<2);while(m--){int u,v;char c[2];scanf("%d%d%s",&u,&v,c);if(c[0] == 'A'){add(u,v,inf,E);du[u]--;du[v]++;num+=E;}else if(c[0] == 'B'){du[u]--;du[v]++;num+=E;}else if(c[0] == 'C'){add(u,v,inf,E);}else add(u,v,1,E);}for(int i = 1;i <= n;++i){if(du[i] > 0){sum += du[i];add(st,i,du[i],0);}else if(du[i] < 0){add(i,ed,-du[i],0);}}
}
int pre[maxn];
int flow[maxn];
int inq[maxn];
int dis[maxn];
int spfa(){memset(pre,-1,ex<<2);memset(inq,0,ex<<2);memset(dis,0x3f,ex<<2);queue<int> q;q.push(st);flow[st] = inf;inq[st] = 1;dis[st] = 0;while(q.size()){int u = q.front();q.pop();inq[u] = 0;for(int i = head[u];i != -1; i = e[i].nxt){int v = e[i].v;if(e[i].f && dis[v] > dis[u] + e[i].w){dis[v] = dis[u] + e[i].w;pre[v] = i;flow[v] = min(flow[u],e[i].f);if(!inq[v]) inq[v] = 1,q.push(v);}}}if(pre[ed] == -1) return -1;return flow[ed];
}
int mfmv(){int fw = 0;int ans = 0;int d;while((d = spfa())!=-1){fw += d;ans += dis[ed]*d;int v = ed;while(v!=st){e[pre[v]].f -= d;e[pre[v]^1].f += d;v = e[pre[v]].u;}}if(fw!=sum) return -1;return ans + num;
}
void sol(){int ans = mfmv();printf("%d\n",ans);
}
int main(){int T;cin>>T;cin>>E>>E;//输入的S没有用,不管它while(T--){init();sol();}
}

ccf-csp 2016-2018部分题目总结相关推荐

  1. ccf csp何以包邮?背包问题思路

    背包问题 问题描述 一个旅行者有一个最多能用M公斤的背包,现在有N件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为V1, V2,..., Vn. 若每种物品只有一件求旅行者能获得最大 ...

  2. 以CCF CSP认证为抓手,积极探索软件基础能力递进式培养体系

    原文链接:以CCF CSP认证为抓手,积极探索软件基础能力递进式培养体系 发布单位:学会      发布时间:2017-01-20 16:16 作者:陆建峰    余立功 摘要:为提升计算机专业类学生 ...

  3. CCF CSP 201609-2 火车购票

    题目链接:http://118.190.20.162/view.page?gpid=T46 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排 ...

  4. 计算机能力挑战赛_蓝桥杯、PAT、CCF CSP、团体程序设计天梯赛、传智杯、计算机能力挑战赛、软考等大学生编程比赛/考试介绍...

    介绍7个适合普通大学生参加的编程比赛/考试(注:有的比赛如蓝桥杯有多种赛别,本文仅介绍其中的程序设计/编程比赛). 编程入门书籍推荐<算法笔记>,内容详细易懂,对新手非常友好,描述语言为C ...

  5. CCF大专委2018年大数据发展趋势预测

    CCF大专委2018年大数据发展趋势预测 周涛,卞超轶,潘柱廷,查礼,程学旗 中国科学院计算技术研究所 论文引用格式:周涛, 卞超轶, 潘柱廷, 等. CCF大专委2018年大数据发展趋势预测[J]. ...

  6. ccf csp寻宝!大冒险!(C语言)

    ccf csp寻宝!大冒险! 题目背景 暑假要到了.可惜由于种种原因,小 P 原本的出游计划取消.失望的小 P 只能留在西西艾弗岛上度过一个略显单调的假期--直到-- 某天,小 P 获得了一张神秘的藏 ...

  7. 【CCF CSP】【Python】【201903-1】小中大

    [CCF CSP][Python][201903-1] 小中大 题目要求 代码实现 主要方法 提交验证 题目要求 代码实现 1.初始版(又名完全原创版.欠优化版.无法体现"人生苦短,我用PY ...

  8. CCF CSP认证考试在线评测系统

    关于CCF CSP认证考试在线评测系统 CCF CSP认证考试简介 CCF是中国计算机学会的简称.CCF计算机软件能力认证(简称CCF CSP认证考试)是CCF于2014年推出,是CCF计算机职业资格 ...

  9. 计算机考csp200分啥水平,计算机与信息工程学院成功举办第20次CCF CSP认证考试

    2020年9月13日,计算机与信息工程学院在计算机大楼201举办第二十次CCF CSP认证考试.这是计算机与信息工程学院2019年12月与中国计算机学会签署协议.河南大学正式成为CSP认证考点以来,举 ...

  10. CCF CSP 序列查询新解

    CCF CSP 序列查询新解(C语言) 题目背景 上一题"序列查询"中说道: A=[A0,A1,A2,⋯,An] 是一个由 n+1 个 [0,N) 范围内整数组成的序列,满足 0= ...

最新文章

  1. samba升级_潮闻快食 | adidas Originals经典鞋款Samba进化升级,C.E x Nike联名系列全释出!...
  2. vc设置ani动画光标
  3. 快报:Java跌惨!Python背后或有推手?网友:心态已崩!
  4. java.util.Scanner应用详解
  5. 关于rabbitmq的介绍
  6. 【翻译】CodeMix使用教程(七):扩展
  7. eclipse中使用svn导出项目,并运行
  8. erp服务器慢_ERP系统服务器维护经验谈
  9. 进程同步与互斥——吸烟者问题源码实现(cigarette smoker’s problem)
  10. 适合程序员使用的键盘有哪些?
  11. 2021年危险化学品经营单位主要负责人考试报名及危险化学品经营单位主要负责人证考试
  12. 计算机网络基础三种交换,数据传输的三种交换方式
  13. 百度网盘提取码_PPT+UI作品集+vi模板(百度网盘链接+取货码)送爱奇YI,优库vip...
  14. 在 Ubuntu 20.04 LTS 桌面版上安装 MS 字体
  15. 改变EDIT框字体大小
  16. PAT-A-1042 Shuffling Machine
  17. 水声信号混响matlab,基于特征匹配的复杂水声信号仿真模型验证方法
  18. 软件项目研发的设计流程
  19. 程序员必知必会之 word 篇
  20. VSCODE设置自动换行后仍然无法在视区宽度内自动换行

热门文章

  1. vba返回excel中所有菜单命令栏CommandBar的名称
  2. 1219_SCons的配置文件SConstruct
  3. mysql数据库完整实例-“汽车维修”
  4. 苹果计算机的桌面图是什么情况,苹果电脑开机后,只能显示电脑桌面,桌面图标都不能显示。怎么办?...
  5. SVG绘制文字特效 html+css
  6. 2017IT在线教育机构汇总
  7. 使用cmd(命令提示符)打开文件磁盘或者文件夹
  8. Java基础 实验四 抽象类和接口
  9. Javaweb项目报告
  10. 美赛论文Latex简易模板 | 快速上手(附注释)