ccf-csp 2016-2018 のいくつかのトピックのまとめ

2016 年 4 月

頂点数

ここに画像の説明を挿入

#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 のすべての行を比較する必要があることに注意してください。同時に、最後の行に競合があり、行がないと競合があります。この 2 つの状況は異なります。

#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的最下面一行row
	for (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] == '/')
				;//说明是绝对路径,无需操作
			else
				tempstr = 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;
}

ゲーム

ここに画像の説明を挿入
この質問は、Inq 配列を設定しない別の BFS です。戻ることができるためですが、これはタイムアウトになります。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;//当前时刻是0
    Q.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;
}

時刻 t に (x, y) に到達したかどうかを示す inq[x][y][t] 配列を設定します。到達した場合は、繰り返し到達する必要がないため、タイムアウトしません。

#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;//当前时刻是0
    Q.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 年 9 月

最大ボラティリティ

ここに画像の説明を挿入

#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;
}

ハースストーン

ベクトルの魔法

#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,生命值为30
	use[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] を使用して、前のパスを見つけます. 最短の長さと、 4 番目の質問
に 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和m
	for (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;
	else
		S = (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;
}

圧縮コーディング

ここに画像の説明を挿入

この問題については、ハフマン木を見てください。ボードの質問かと思いましたが、後でそうではないことがわかりました.このコードはハフマンとは異なります.ハフマンボードで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)//如果蛋糕分完了还是不够k
		num++;
	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;
}

マークダウン

ここに画像の説明を挿入
これは文字列処理の古典的な問題です.
ここでの文字列処理は非常に強力です. 参考にしてください.

#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;
}



地下鉄建設

ここに画像の説明を挿入

最短経路: 考えられるすべての経路の中で最も時間が短い経路が答えであり、最短日数は経路の中で最も建設時間が長いトンネルに依存するため、最大値の中から最小値を見つける問題です。 . エッジ u->v に対して dijkstra または spfa を再度実行し、dis[v] を更新するときは、最初に前任者の最短パス dis[u] と u->v の重みを比較し、大きい方を tmpdis として、次に tmpdis を使用します。

最短パスでは同期をオフにする必要があることに注意してください。そうしないと、タイムアウトになります。最小スパニング ツリーでは、同期をオフにする必要はありません。

ダイクストラのコードは次のとおりです。

#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;
}
 

最小全域木+ユニオン探索法同時に作業を開始したので、質問の意味は、最小全域木の中で最大の辺の重みを見つけることだと理解できます。したがって、すべてのエッジを重みの昇順で並べ替えることができ、ノード 1 とノード n が同じルートを持つまで、クルスカル アルゴリズムを使用してエッジの 2 つのポイントに対してマージ操作を実行します。始点と終点を結び、現在動作中のエッジの重みが答えです。

#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 年 9 月

しょうゆ

ここに画像の説明を挿入

#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で定義したほうがいいことがわかりました。
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];
		else
			s += 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;
	}
	//得到了最终的一长串str
	for (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;
		else
			cout << "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->v
			for (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->v
			for (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可以访问到v
    r[v][u] = true; //v可以访问到u
    vis[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;
}

フロイドは距離を計算することもできます

分割

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)//末位是k
		return 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;
}

クロンタブ

ここに画像の説明を挿入
サンプルはコードを実行し、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;
	else
		return 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))//如果是闰年,额外加1
			sum += 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.处理min
	if (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.处理hours
	if (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.处理dayOfMonth
	if (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.处理month
	if (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.改month
	for (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.改dayofweek
	for (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;
    else
        return 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;
    else
        return -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);
        else
            val1 = getval(s);
        v.push_back(make_pair(val1, val1));
    }
    else {
    
    
        if (isdigit(s[0]))
            val1 = atoi(s);
        else
            val1 = getval(s);
        if (isdigit(s[p2]))
            val2 = atoi(s + p2);
        else
            val2 = 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]);
        }
        // Command
        cin >> 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;
				else
					score += 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;
	else
		return 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();//清楚flga
	int 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年9月

野菜の販売

ここに画像の説明を挿入

#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 合併

ここに画像の説明を挿入
第1ステップと第2ステップを完了すると、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变为0
	str1 = 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.第一步:排序//60
	sort(iplist, iplist + n, cmp);
	//2.第二步:从小到大合并//80
	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)
				{
    
    
					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();
	}
} 

おすすめ

転載: blog.csdn.net/susuate/article/details/120337283