杭电历年真题(自用)

2006-2009

2.A+B

输入两个非常大的整数(完全超出了int、long的表示范围),这个整数的长度可能超过100位,计算并输出这两个数相加的结果。(HDU acm 1002 用string处理比较好)

#include <stdio.h>
#include <string>
#include<String.h>
using namespace std;

int main() {
	char a[10000], b[10000];
	int c[10000];
	int n;
	int i, j, k;
	cin >> n;
	while (n--) {
		cin >> a >> b;
		int len_a = strlen(a);
		int len_b = strlen(b);
		int d = 0;
		for (i = len_a-1, j = len_b-1,k=0; i >=0&&j >=0; i--, j--,k++) {
			c[k] = (a[i]-'0' + b[j]-'0' + d) % 10;
			if (a[i] - '0' + b[j] - '0' +d > 9)
				d = 1;
			else d = 0;
		}
		//a还没有计算完
		while (i >= 0) {
			c[k] = a[i] - '0' + d;
			k++; i--; d = 0;
		}
		//b还没有计算完
		while (j >= 0) {
			c[k] = b[j] - '0' + d;
			k++; j--; d = 0;
		}

		for (int i = k-1; i >= 0; i--)
			cout <<c[i];
		cout << endl;
	}
}

5.

输入一个长整型的数,从低位起取出奇数位组成一个新的数输出。

int main() {
	long n;
	long sum = 0;
	int m = 1;
	cin >> n;
	for (int i = 0; n != 0; i++) {
		if (i % 2 == 1) {
			sum += n % 10 * m;
			m = m * 10;
		}
		n = n / 10;
	}
	cout << sum << endl;
}

6

输入n个字符串,将它们按字母由小到大的顺序排列并输出。

int main(){
    int n;
    cin>>n;
    string p[100];
    for(int i=0;i<n;i++)
        cin>>p[i];//需添加<string>头文件
    sort(p,p+n);
    for(int i=0;i<n;i++)
        cout<<p[i]<<endl;
    return 0;
} 

2010

1.猜随机数

随即产生一个3位的正整数,让你进行猜数字,如果猜小了,输出:“猜小了,请继续”。如果猜大了,输出:“猜大了,请继续”。如果猜对了。输出:“恭喜你,猜对了”。不过最多只能猜10次,如果猜了10次还没有猜对,就退出程序,输出:“Bye Bye”。

随机数的生成:
srand(time(0));
n = rand()%1000;
生成0-999的随机数

#include<iostream>
#include <stdio.h>
#include <string>
#include<String.h>
#include<ctime>
using namespace std;

int main() {
	srand(time(0));
	int n = rand()%1000;
	int a;
	int i = 10;
	int flag;
	while (i--) {
		cin >> a;
		flag = 0;
		if (a == n) {
			cout << "恭喜你猜对了" << endl;
			flag = 1;
			break;
		}
		else if (a > n)
			cout << "猜大了,请继续" << endl;
		else if (a < n)
			cout << "猜小了,请继续" << endl;
	}
	if (flag == 0)
		cout << "Bye Bye" << endl;
}


2.字符求和

写函数 FindAndSum,输入一个字符串,把字符串中的数字作为整数进行求和,并输出结果。Sample : 输入:There are some apple. 输出:0 。输入:124and 1524 输出:1648 。

#include<iostream>
#include <stdio.h>
#include <string>
#include<String.h>
#include<ctime>
using namespace std;
int FindAndSum(char *str) {
	int len = strlen(str);
	int a = 0, sum = 0;
	for (int i = 0; i < len; i++) {
		if (str[i] >= '0'&&str[i] <= '9') {
			a += str[i] - '0';
			if (str[i + 1] >= '0'&&str[i + 1] <= '9')
				a = a * 10;
			else
			{
				sum += a;
				a = 0;
			}
		}
	}
	return sum;
}

int main() {
	char str[1000];
	while (gets_s(str)) {
		cout << FindAndSum(str) << endl;
	}
}


3.文件操作和结构体对象数组

处理一个文件 student.txt,文件当中包括一组学生的信息,包括名字、学号、英语成绩、语文成绩、数学成绩、科学成绩,如下:
姓名 学号 英语 语文 数学 科学
张三 20100601 78 89 62 75
李四 20100602 78 54 98 86
王五 20100603 78 69 85 75
……………………………………
从这个文件当中读入学生的信息,然后按照总成绩从高到低进行排序并输出学生信息。

#include<iostream>
#include <stdio.h>
#include <string>
#include<String.h>
#include<fstream>
using namespace std;

typedef struct student {
	char name[20];
	char id[20];
	int a;
	int b;
	int c;
	int d;
}student;

bool cmp(student m, student n) { 
	return m.a + m.b + m.c + m.d > n.a + n.b + n.c + n.d; }

int main() {
	student stu[100];
	fstream in;
	//打开文件,只读
	//C++中打开文件是文件对象,不是文件指针。
	in.open("C:\\Users\\pc\\Desktop\\student.txt", ios::in);
	if (!in.is_open()) {
		cout << "student.txt 打开文件失败!!"<<endl;
	}
	int n = 0;
	while (!in.eof()) {
		if (n == 0) {  //处理第一行表头
			string s;
			getline(in, s);
		}
		else {
			in >> stu[n].name >> stu[n].id;
			in >> stu[n].a >> stu[n].b >> stu[n].c >> stu[n].d;
		}
		n++;
	}
	in.close();  //文件关闭
	sort(stu, stu + n, cmp);
	for (int i = 1; i < n; i++) {
		cout << i << "." << stu[i].name << " " << stu[i].id << endl;
	}
	return 0;
}


2011

2.三天打鱼两天晒网

有个人从2003年1月1日开始,三天打鱼两天晒网,请输入月份、日期,问在当年的某一天他是在打鱼还是在晒网。

int main() {
	int m, d;
	cin >> m >> d;
	int month[13] = { 0,30,28,31,30,31,30,31,31,30,31,30,31 };
	int sum = 0;
	for (int i = 1; i < m; i++) {
		sum += month[i];
	}
	sum += d;
	int r = sum % 5;
	if (r >= 1 && r <= 3)
		cout << "打鱼" << endl;
	else
		cout << "晒网" << endl;
}

3.丑数

丑数是这样定义的:如果一个正整数的素因子只包含 2、3、5、7 四种,则它被称为丑数。以下数列 1, 2, 3,4, 5,6,7,8,9, 10,12,14,15,16,18, 20, 21,24,25, 27………. 就显示了前 20 个丑数。给出一个正整数 N,判断这个数是否为丑数

int main() {
	int n;
	cin >> n;
	while (n--) {
		int a;
		cin >> a;
		int r[4] = { 2,3,5,7 };
	
		for (int i = 0; i <4; i++) {
			if (a%r[i] == 0) {
				a = a / r[i];
				i--;
			}	
		}
		if (a != 1)
			cout << "No" << endl;
		else
			cout << "Yes" << endl;
	}
}

2012

1.十进制转十六进制

void trans_r(int n, int r) {
	if (n / r == 0)
		cout << n % r;
	else {
		trans_r(n / r, r);
		int m = n % r;
		if (m > 9)
			printf("%c", m - 10 + 'A');
		else
			cout << m;
	}
}

int main() {
	int n;
	while (cin >> n) {
		trans_r(n, 16);
	}
	return 0;
}

2.贪吃蛇

2013

1.时间A-B

输入一个数,代表要检测的例子的个数,每个例子中:
输入两个时间(格式HH:MM:SS),前面时间减去后面时间,输出在时钟上显示的时间,格式一样,如果是以为数字的前面补零。

int main() {
	int n;
	cin >> n;
	int h1, m1, s1, h2, m2, s2;
	int h, m, s;
	while (n--) {
		scanf_s("%d:%d:%d", &h1, &m1, &s1);
		scanf_s("%d:%d:%d", &h2, &m2, &s2);
		if (s1 - s2 >= 0)
			s = s1 - s2;
		else {
			s = s1 - s2 + 60;
			m1--;
		}
		if (m1 - m2 >= 0)
			m = m1 - m2;
		else {
			m = m1 - m2 + 60;
			h1--;
		}
		if (h1 - h2 >= 0)
			h = h1 - h2;
		else {
			h = h1 - h2 + 24;
		}
		printf("%02d:%02d:%02d\n", h, m, s);
	}
}

2.图 不会写!

一个活动有N个人参加,一个主持人和N-1个普通参加者,其中所有的人都认识主持人,主持人也认识所有的人,主持人要求N-1个参加者说出他们在参加者中所认识的人数,如果A认识B,则B认识A,所以最少是会认识一个人,就是主持人,他们说出了自己所认识的人数后,需要判断他们中有没有人说谎。
输入:
第一行是N,N = 0表示结束
第二行是N - 1个数字
输出:
Lie absolutely 或者 Maybe truth
7
1 2 4 5 5 3

9
3 7 7 7 7 5 6 6
两个测试例子中第一个是Lie absolutely,第二个是Maybe truth

/*思路:一共有N个人,除去主持人共有N-1个人,这N-1个人都说了自己认识的人数(至少为1,因为每个人都认识主持人),认识都是相互的,A认识B,则B也认识A,N-1个人按照所认识的人数从高到低排序;
比如输入N个数,再输入N-1个数
9
3 7 7 7 7 5 6 6
先把这8(N-1)个数从高到低排序,7 7 7 7 6 6 5 3,第一个人说认识7个人,除了主持人以外还认识6个人,就当作是靠近他的后面6个人,除去第一个人,那么后面的人所说的认识的人数需要减去1,
变为7 6 6 6 5 5 4 3 ,再次排序变为7 6 6 6 5 5 4 3;(注意:排序的话只要将出第一个人以外的重新排序就好,因为第一个没有改变数值,其余的都可能改变了)
第二个人说认识6个人,除了主持人以外还认识5个人,就当作是靠近他的后面5个人,除去第二个人,那么后面的人所说的认识的人数需要减去1,
变为7 6 5 5 4 4 3 3,再次排序变为7 6 5 5 4 4 3 3;
第三个人说认识5个人,除了主持人以外还认识4个人,就当作是靠近他的后面4个人,除去第三个人,那么后面的人所说的人数需要减去1,
变为7 6 5 4 3 3 2 3,再次排序变为7 6 5 4 3 3 3 2;
第四个人说认识4个人,除了主持人以外还认识3个人,就当作是靠近他的后面的3个人,除去第四个人,那么后面的人所说的人数需要减去1,
变为7 6 5 4 2 2 2 2,再次排序变为7 6 5 4 2 2 2 2;
第五个人说认识2个人,除了主持人以外还认识1个人,就当作是靠近他的后面的1个人所说的人数减1,
变为7 6 5 4 2 1 2 2,再次排序变为7 6 5 4 2 2 2 1;
第六个人说认识2个人,除了主持人以外还认识1个人,就当作是靠近他的后面的1个人所说的人数减1,
变为7 6 5 4 2 2 1 1,再次排序变为7 6 5 4 2 2 1 1;
第七个人说认识1个人,说明他只认识主持人;
第八个人说认识1个人,说明他只认识主持人。
*/
bool cmp(int a,int b) {
	return a > b;
}
int main() {
	int n;
	int a[100];
	while (cin >> n) {
		//记得要先n-1
		n = n - 1;
		
		for (int i = 0; i < n; i++)
			cin >> a[i];
		for (int i = 0; i < n ; i++) {
			sort(a, a + n, cmp);
			if (a[n - 1] == 0)
			{
				cout << "Lie absolutely" << endl;
				break;
			}
			if (a[i] == 1) {
				if (a[n - 1] == 1)
					cout << "Maybe truth" << endl;
				else
					cout << "Lie absolutely" << endl;
				break;
			}
			
			//减
			int m = a[i]-1;
			for (int j = i + 1; j <= i + m;j++) {
				a[j]--;
			}
		}
	}
}

2014

1.html 杭电oj 1088

输入:
Hallo, dies ist eine
ziemlich lange Zeile, die in Html
aber nicht umgebrochen wird.


Zwei

produzieren zwei Newlines.
Es gibt auch noch das tag


was einen Trenner darstellt.
Zwei

produzieren zwei Horizontal Rulers.
Achtung mehrere Leerzeichen irritieren

Html genauso wenig wie

mehrere Leerzeilen.

int main() {
	char str[100];
	int c=0;//用于记录改行已输出的字符数
	while (cin >> str) {
		
		if (strcmp(str, "<br>") == 0) {
			cout << endl;
			c = 0;
			continue;
		}
		else if (strcmp(str, "<hr>") == 0) {
			if(c>0)
				cout << endl;
			for (int i = 0; i < 80; i++)
				cout << '-';
			cout << endl;
			c = 0;
			continue;
		}
		else {
			int len = strlen(str);
			if (c + len+1 > 80) {//+1空格
				cout << endl;
				c = 0;
			}
			if (c == 0) {
				cout << str;
				c += len ;
			}
			else {
				cout << ' ' << str;
				c += len+1;
			}
		}
	}
	//别忘了最后一行的输出
	if (c != 0)
		cout << endl;	
}

2.Encoding (杭电oj 1020)


int main() {
	int n;
	char str[10000];
	cin >> n;
	while (n--) {
		cin >> str;
		int len = strlen(str);
		char c = str[0];
		int sum = 0;
		for (int i = 0; i < len; i++) {
			if (c == str[i])
				sum++;
			else {
				if (sum > 1) {
					cout << sum << str[i - 1];
				}
				else
					cout << str[i - 1];
				c = str[i];
				sum = 1;
			}
 		}
		if (sum == 1)
			cout << str[len - 1] << endl;
		else
			cout << sum << str[len - 1] << endl;
		
	}
}

2015

1.字符串中数字相加

给定一个字符串,计算字符串中数值的个数并求和。其中还包含了负号,若紧跟负号的是一个数值,则表示这是一个负数,若后面跟着的不是数字,则不表示什么。


int main() {
	int n;
	char str[100];
	while (cin >> str) {
		int sum = 0;
		int len = strlen(str);
		int a = 0,flag = 0,num = 0;
		for (int i = 0; i < len; i++) {
			//负数判断
			if (str[i] == '-'&&isdigit(str[i+1])) 
				flag = 1;
			//先把数字存下来
			if (isdigit(str[i])) 
				a = a+str[i] - '0';
			//对下一位判断,是数字则x10,否则结束该数字
			if (isdigit(str[i + 1])) {
				a = a * 10;
			}
			else {
				if (flag == 1)
					a = a * (-1);
				sum += a;
				a = 0;
				flag = 0;
				if (isdigit(str[i]))
					num++;
			}
		}
		cout << num << ' ' << sum << endl;

	}
}

2.DFS判断连通块

给定一个数字矩阵,如果上下左右数值相同,则表示是一个连通的区域。求矩阵中连通块的数量
参考:https://blog.csdn.net/weixin_42264284/article/details/105613174

#include<queue>
using namespace std;

const int maxn = 110;

struct node {
	int x, y;
}Node;//位置节点,写成一个结构体 

int matrix[maxn][maxn];
bool inq[maxn][maxn] = { false };//标记数组,记录某一位置是否入过队 
int n, m;//n行m列
int X[4] = { 0,0,1,-1 };//增量数组,因为BFS访问时是上下左右一圈相邻的都得访问 
int Y[4] = { 1,-1,0,0 }; //设置数组后就可以用for循环来实现,避免枚举四次位置 

//用BFS遍历 
/*枚举每个位置的数先记录当前的数,然后用BFS遍历与该位置相邻的四个位置,判断他们是否与之相等,若想等
则同样去查询相邻的位置并将其做标记,以免走回头路,所以这里的标记数组是二维的,表示某一位置是否被访问过
*/
bool judge(int x, int y, int value) {//判断这个位置是否可以访问 
	if (x < 0 || x >= n || y < 0 || y >= m) {//越界 
		return false;
	}
	if (matrix[x][y] != value || inq[x][y] == true) return false;//已经访问过的顶点或者不是一个数值的不在访问
	return true;
}
//BFS函数访问(x,y)所在的位置快等于value的元素,将该块所有元素inq置为true 
void BFS(int x, int y, int value) {
	queue<node> Q;//定义队列 
	Node.x = x;
	Node.y = y;
	//	int temp=matrix[x][y];
	Q.push(Node);//起始位置节点入队
//	inq[x][y]=true;//在入队时就将元素做访问标记,避免重复入队
	while (!Q.empty()) {
		node top = Q.front();//取出队头元素
		inq[top.x][top.y] = true;
		Q.pop();//队头元素出队
//		printf("x=%d,y=%d ",top.x,top.y);//测试所加 
		for (int i = 0; i < 4; i++) {
			int newx = top.x + X[i];//设置newx可以保留top.x中的值 
			int newy = top.y + Y[i];
			if (judge(newx, newy, value)) {//如果这个位置可以访问 
				Node.x = newx, Node.y = newy;//
				Q.push(Node);//节点入队 
				inq[newx][newy] = true;
			}
		}
	}
}
//DFS将同一个连通块中的元素做标记 
void DFS(int x, int y, int value) {
	//cout << x<<" " <<y << endl;
	//递归边界 
	if (x < 0 || x >= n || y < 0 || y >= m) {//越界返回 
		return;
	}
	//已经访问过的顶点或者不是一个数值, 递归边界返回
	if (matrix[x][y] != value || inq[x][y] == true) 
		return; 
	for (int i = 0; i < 4; i++) {//往四个方向递归 
		inq[x][y] = true;//做访问标记 
		DFS(x + X[i], y + Y[i], value);
	}

}

int main() {
	scanf_s("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf_s("%d", &matrix[i][j]);
		}
	}

	int ans = 0;//存储连通块数
	for (int x = 0; x < n; x++) {
		for (int y = 0; y < m; y++) {//枚举每一个位置 
		//如果元素未入过队	
			if (inq[x][y] == false) {
				int value = matrix[x][y];
				ans++;
				//BFS(x,y,value);//将matrix矩阵中的同一连通快全部访问并做标记
				DFS(x, y, value);
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}

2016

2.求最近的两点距离

在一个二维平面内有n个点,每个点坐标为(x,y),求最近的两点的距离。(暴力求解即可)

typedef struct pos {
	int x;
	int y;
};
int dis(pos a, pos b) {
	return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}
int main() {
	int n;
	cin >> n;
	pos p[100];
	for (int i = 0; i < n; i++)
		cin >> p[i].x >> p[i].y;
	int min = 1000000;
	for (int i = 0; i < n-1; i++) {
		for (int j = i+1; j < n; j++) {
			if (dis(p[i], p[j]) < min) {
				min = dis(p[i], p[j]);
			}
		}
	}
	double d = sqrt(min*1.0);
	cout << d << endl;
}

3.文件读出

有一个文件记录了学生期末考试的几门成绩和学号,求出这几门课程的平均分和总分,并按照总分排序,从高到底,如果成绩相同,按照学号从小到大的顺序。

#include<iostream>
#include <stdio.h>
#include<algorithm>
#include<fstream>
using namespace std;

typedef struct stu {
	char name[20];
	int id;
	int a;
	int b;
	int c;
};
bool cmp(stu m, stu n) {
	if (m.a + m.b + m.c != n.a + n.b + n.c)
		return m.a + m.b + m.c > n.a + n.b + n.c;
	else
		return m.id < n.id;
}
int main() {
	fstream in;
	stu s[2000];
	in.open("C:\\Users\\pc\\Desktop\\stu.txt", ios::in);
	if (!in.is_open())
		cout << "error" << endl;
	int n = 0;
	while (!in.eof()) {
		//第一行表头
		if (n == 0) {
			string s;
			getline(in,s);
		}
		else {
			in >> s[n].name >> s[n].id;
			in >> s[n].a >> s[n].b >> s[n].c;
		}
		n++;
	}
	in.close();
	sort(s+1, s + n, cmp);
	for (int i = 1; i < n; i++) {
		if (i == 1)
			cout << s[i].name;
		else
			cout << " " << s[i].name;
	}
}

4.求两矩阵绝对值之差的和的最小值

有一个由数字组成的二维矩阵,大小为 NM;还有一个大小为 nm 小二维矩阵,想象将小二维矩阵上面(小矩阵左上角位置和大矩阵某个位置对应放置),在不同的位置,这两个二维矩阵对应位置的数字绝对值之差的和一般是不同的,求这个绝对值之差的和的最小值,并求出对应的大矩阵位置

int main() {
	int N, M, n, m;
	int a[100][100];
	int b[100][100];
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> a[i][j];
		}
	}
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> b[i][j];
		}
	}
	int sum = 0;
	int min = 100000, min_i, min_j;
	for (int i = 0; i <= N - n; i++) {
		for (int j = 0; j <= M - m; j++) {
			for (int ii = 0; ii < n; ii++) {
				for (int jj = 0; jj < m; jj++) {
					sum += abs(a[i+ii][j+jj] - b[ii][jj]);
				}
			}
			if (sum < min) {
				min = sum;
				min_i = i;
				min_j = j;
				sum = 0;
			}
		}

	}
	cout << min << " (" << min_i + 1 << "," << min_j + 1 << ")" << endl;

}

2017

1.素数判断

关羽过关斩三将,输入四个人的武力值(大于 0 小于 50),若超过界限需要重新输入,关羽的武力值 x,将士武力值为 y,满足(x-y)^2+(x-y)+41 若为素数则关羽获胜,若关羽三次获胜输出 WIN,若失败则输出失败的将领序号(第几关)

void input(int &x) {
	while (x <= 0 || x >= 50) {
		cout << "input again" << endl;
		cin >> x;
	}	
}
int is_prime(int x) {
	for (int i = 2; i <= x / 2; i++) {
		if (x%i == 0)
			return 0;
	}
	return 1;
}
int main() {
	int x, y;
	cin >> x;
	input(x);
	int n = 0, win = 0;
	while (n<3) {
		cin >> y;
		input(y);
		if (is_prime((x - y)*(x - y) + (x - y) + 41))
			win++;
		else {
			cout << n + 1 << endl;
			break;
		}
		n++;
	}
	if (win == 3)
		cout << "WIN" << endl;
	
}

2.时间比较

输入 N 个员工,每个员工输出 ID 号,上班时间,下班时间,
第一行输出最早去的员工的 ID 和上班时间
第二行输出最迟走的员工的 ID 和下班时间
第三行输出工作最久的员工的 ID 和上班时间


typedef struct yuangong {
	char id[20];
	int h1, m1, s1, h2, m2, s2;
}yuangong;

int cmp1(yuangong m, yuangong n) {
	if (m.h1 != n.h1)
		return m.h1 < n.h1;
	else if (m.m1 != n.m1)
		return m.m1 < n.m1;
	else if (m.s1 != n.s1)
		return m.s1 < n.s1;
}

int cmp2(yuangong m, yuangong n) {
	if (m.h2 != n.h2)
		return m.h2 > n.h2;
	else if (m.m2 != n.m2)
		return m.m2 > n.m2;
	else if (m.s2 != n.s2)
		return m.s2 > n.s2;
}
int worktime(yuangong a) {
	return (a.h2 - a.h1) * 3600 + (a.m2 - a.m1) * 60 + (a.s2 - a.s1);
}
int cmp3(yuangong m, yuangong n) {
	return worktime(m) > worktime(n);
}

int main() {
	int n;
	yuangong yg[100];
	cin >> n;
	int minh = 23, minm = 59, mins = 59;
	int maxh = 0, maxm = 0, maxs = 0;
	for (int i = 0; i < n; i++) {
		cin >> yg[i].id;
		scanf_s("%d:%d:%d", &yg[i].h1, &yg[i].m1, &yg[i].s1);
		scanf_s("%d:%d:%d", &yg[i].h2, &yg[i].m2, &yg[i].s2);	
	}
	sort(yg, yg + n, cmp1);
	cout << yg[0].id << " ";
	printf("%02d:%02d:%02d\n", yg[0].h1, yg[0].m1, yg[0].s1);
		
	sort(yg, yg + n, cmp2);
	cout << yg[0].id << " ";
	printf("%02d:%02d:%02d\n", yg[0].h2, yg[0].m2, yg[0].s2);
	
	sort(yg, yg + n, cmp3);
	cout << yg[0].id << " ";
	printf("%02d:%02d:%02d\n", yg[0].h1, yg[0].m1, yg[0].s1);

}

3.切模板

有一个MN的材料和一个st的模板,从材料中切除模板,求最大能切出来的模板的数量。

int main() {
	int N, M, s, t;
	char a[100][100];
	char b[100][100];
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> a[i][j];
		}
	}
	cin >> s >> t;
	for (int i = 0; i < s; i++) {
		for (int j = 0; j < t; j++) {
			cin >> b[i][j];
		}
	}
	int sum = 0;
	int min = 100000, min_i, min_j;
	int flag = 0;
	for (int i = 0; i <= N - s; i++) {
		for (int j = 0; j <= M - t; j++) {
			flag = 0;
			for (int ii = 0; ii < s; ii++) {
				for (int jj = 0; jj < t; jj++) {
					if (flag == 0) {
						if (a[i + ii][j + jj] != b[ii][jj]) {
							//代表该块不用再对比了了
							flag = 1;
						}
						//若顺利对比到最后一个且最后一个对比成功
						if (ii == s - 1 && jj == t - 1 && (a[i + ii][j + jj] == b[ii][jj])) {
							sum++;
							//把对比成功的这块大模板区域标记
							for (int k = i; k < s + i; k++) {
								for (int l = j; l < t + j; l++) {
									a[k][l] = '0';
								}
							}
						}

					}
					
				}
			}
			
		}
	}
	cout << sum << endl;
}

2018

1.签到题

5
Bob 9
Alice 12
Tom 5
Listen 7
Nick 4

typedef struct student {
	char name[20];
	int a;
}student;

int is_ugly(int x) {
	int flag = 0;
	int a[3] = { 2,3,5 };
	for (int i = 0; i < 3; i++) {
		if (x%a[i] == 0) {
			x = x / a[i];
			i--;
		}
	}
	if (x != 1)
		return 0;
	else
		return 1;
}
int cmp(student m, student n) {
	return m.a < n.a;
}

int main() {
	int n;
	cin >> n;
	student stu[100];
	for (int i = 0; i < n; i++) {
		cin >> stu[i].name >> stu[i].a;
	}

	//1.1丑数
	cout << "1.1" << endl;
	for (int i = 0; i < n; i++) {
		if (is_ugly(stu[i].a))
		{
			cout << stu[i].name << endl;
		}
	}
	cout << endl;
	
	//1.2 对a升序排序
	cout << "1.2" << endl;
	sort(stu, stu + n, cmp);
	for (int i = 0; i < n; i++)
		cout << stu[i].name << endl;
	cout << endl;

	//1.3 插入新名字并排序
	cin >> stu[n].name >> stu[n].a;
	student temp = stu[n];
	for (int i = n - 1; i >= n / 2; i--) {
		stu[i + 1] = stu[i];
	}
	stu[n / 2] = temp;
	for (int i = 0; i < n+1; i++)
		cout << stu[i].name << endl;
}

2.毕业照

2.修管道

2019

1.签到题

2.体积最大

int main() {
	int n;
	cin >> n;
	int a[100];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	int max = 0;
	int s = 0;
	for (int i = 0; i < n-1; i++) {
		for (int j = i; j < n; j++) {
			if (a[i] <= a[j])
				s = (j - i)*a[i];
			else
				s = (j - i)*a[j];
			if (s > max)
				max = s;
		}
	}
	cout << max << endl;
}

3.卷积

4.DFS 好友圈

有一群人,现在告诉你他们之间的朋友关系。若 A 与 B 是朋友,B 是 C 的朋友,则 A 与 C 也是朋友。朋友关系都是双向的,即 A 与 B 是朋友,B 与 A 也是朋友。那么 A、B、C 就在同一个 “朋友圈”
input:
8 7
1 2
2 4
4 1
5 7
4 3
6 2
7 8

//用邻接矩阵来表示邻接表
int map[2001][2001];
bool vis[2001];
void DFS(int u, int n) {
	cout << u << " " << n;
	vis[u] = true;                  //标记为已访问
	for (int i = 1; i <= n; i++) {  //对每个顶点
		if (!vis[i] && map[u][i]) {
			vis[i] = true;
			DFS(i, n);
		}
	}
}
int main() {
	int n, m, a, b, count = 0;
	memset(map, 0, sizeof(map));
	memset(vis, false, sizeof(vis));
	cin >> n >> m;
	while (m--) {
		cin >> a >> b;
		map[a][b] = map[b][a] = 1;
	}
	
	for (int i = 1; i <= n; i++) {
		if (!vis[i]) {  //若未访问
			DFS(i, n);
			count++;  //联通分量个数
		}
	}
	cout << count << endl;
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值