北大信科夏令营机考题分类汇总

巧妙的方法

1. 护林员盖房子(2019信科研究生上机测试)

这个题目与leetcode85题为一题。利用了一个很玄妙的栈。


#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
#include<map>
#include<stack>
using namespace std;

int graph[21][21];

int getMaxArea(vector<int> heights) {
	stack<int> s;
	s.push(-1);
	int maxArea = -1;
	for (int i = 0; i < heights.size(); i++)
	{
		while (s.top() != -1 && heights[s.top()] >= heights[i])
		{
			int peek = s.top();
			s.pop();
			int peek2 = s.top();
			maxArea = max(maxArea, heights[peek] * (i - peek2 - 1));
		}
		s.push(i);
	}
	while (s.top()!=-1)
	{
		int peek = s.top();
		s.pop();
		int peek2 = s.top();
		maxArea = max(maxArea, (int)heights[peek] * (int)(heights.size() - peek2 - 1));
	}
	return maxArea;
}
int main()
{
	int n, m;
	cin >> n >> m;
	vector<int> heights(m, 0);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> graph[i][j];
		}
	}
	int maxArea = -1;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (graph[i][j] == 0)
			{
				if (i > 0 && graph[i-1][j] == 0)
					heights[j]++;
				else
					heights[j] = 1;
				
			}
			else
			{
				heights[j] = 0;
			}
		}
		maxArea = max(maxArea, getMaxArea(heights));
	}
	cout << maxArea << endl;
	return 0;
}

 

2. Game Prediction(2018年北京大学软件工程学科夏令营上机考)

这是一道贪心算法的题目,刚开始看感觉挺难的,看了解析之后其实挺简单。

https://blog.csdn.net/daphne566/article/details/57130311

 

3. 出栈序列的模拟(2018大数据研究中心夏令营上机考试)

应该还算简单吧

https://blog.csdn.net/hentaidesu/article/details/50117815

4. 字符串排序(2018研究生上机测)

字符串逆序对问题,解法有归并排序,线段树?后面要好好看。

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
#include<map>
#include<stack>

using namespace std;
vector<int> values;
long long int res = 0;
void sort(int left, int right);
void merge2(int left, int mid, int right);
void sort(int left, int right) {
	if (left >= right)
		return;
	int mid = (left + right) / 2;
	sort(left, mid);
	sort(mid + 1, right);
	merge2(left,mid,right);
}

void merge2(int left, int mid, int right) {
	vector<int> l;
	vector<int> r;
	for (int i = left; i <= mid; i++)
	{
		l.push_back(values[i]);
	}
	for (int i = mid + 1; i <= right; i++)
	{
		r.push_back(values[i]);
	}
	int lIndex = 0;
	int rIndex = 0;
	int index = left;
	while (lIndex <= mid - left && rIndex < right - mid)
	{
		if (l[lIndex] <= r[rIndex])
		{
			values[index] = l[lIndex];
			index++;
			lIndex++;
		}
		else
		{
			values[index] = r[rIndex];
			res = res + mid-left - lIndex+1;
			index++;
			rIndex++;
		}
	}
	while (lIndex <= mid - left)
	{
		values[index] = l[lIndex];
		index++;
		lIndex++;
	}
	while (rIndex < right - mid)
	{
		values[index] = r[rIndex];
		index++;
		rIndex++;
	}
}
int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int tmp;
		cin >> tmp;
		values.push_back(tmp);
	}
	sort(0, n - 1);
	cout << res << endl;
	return 0;
}

5. 特殊密码锁(2017大数据研究中心夏令营上机考试)

https://blog.csdn.net/yichuan_sun/article/details/79744183

 

简单题目

 

1. 放便记忆的电话号码(2019信科研究生上机测试)

2. 区间内的真素数(2018研究生推免上机考)

3. 简单密码(2018研究生推免上机考)

4. 最简真分数*(2018研究生推免上机考)

这里的gcd辗转相除要会用。

#include <iostream>
#include<string>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
int gcd(int a, int b)
{
	int t;
	if (a < b) t = a, a = b, b = t;
	if (b == 0) return a;
	t = a % b;
	while (t != 0)
	{
		a = b;
		b = t;
		t = a % b;
	}
	return b;
}

int main()
{
	int n;
	cin >> n;
	vector<int> values(n);
	int count = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> values[i];
	}
	for (int i = 0; i < n-1; i++)
	{
		for (int j = i + 1; j < n; j++)
		{
			if (gcd(values[i], values[j]) == 1)
				count++;
		}
	}
	cout << count << endl;
	return 0;


}

5. 垂直直方图( 2018年北京大学软件工程学科夏令营上机考试)

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
#include<map>
#include<stack>
using namespace std;
int heights[26];
int main()
{
	string s = "";
	for (int i = 0; i < 4; i++)
	{
		string tmp;
		getline(cin, tmp);
		s += tmp;
	}
	int maxHeight = -1;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] >= 'A'&&s[i] <= 'Z')
		{
			heights[s[i] - 'A']++;
			if (maxHeight < heights[s[i] - 'A'])
			{
				maxHeight = heights[s[i] - 'A'];
			}
		}
	}
	int end = maxHeight;
	for (int i = 0; i < end; i++)
	{
		for (int j = 0; j < 26; j++)
		{
			if (maxHeight - heights[j] <= 0)
				cout << "* ";
			else
				cout << "  ";
		}
		cout << endl;
		maxHeight--;
	}
	for (int j = 0; j < 26; j++)
	{
		char tmp = 'A' + j;
		cout << tmp<<" ";
	}
	cout << endl;
	return 0;
}

6. 两个日期之间的天数(2018计算机学科夏令营上机考试)

这题表面简单,很耗费时间啊,要想明白,从简单到复杂的情况一步步来。

7. 回文字串(2018计算机学科夏令营上机考试)

8. 第n小的质数(2018大数据研究中心夏令营上机考试)

9. 潜伏者(2018大数据研究中心夏令营上机考试)

#include <iostream>
#include<string>
#include<math.h>
#include<map>
#include<set>
using namespace std;


int main()
{
	string oldPass, old, pass;
	cin >> oldPass >> old >> pass;
	map<char, char> m;
	set<char> s;
	int counter = 0;
	for (int i = 0; i < old.length(); i++)
	{
		char cPass = oldPass[i];
		char cOld = old[i];
		auto cur = m.find(cPass);
		auto ch = s.find(cOld);
		if (cur==m.end()&&ch==s.end())
		{
			m.insert(pair<char, char>(cPass, cOld));
			s.insert(cOld);
			counter++;
		}
		else if (cur->second != cOld)
		{
			cout << "Failed" << endl;
			return 0;
		}
		if (counter == 26)
			break;
	}
	if (counter < 26)
	{
		cout << "Failed" << endl;
		return 0;
	}
	string result = "";
	for (int i = 0; i < pass.length(); i++)
	{
		auto c = m.find(pass[i]);
		result.append(1, c->second);
	}
	cout << result << endl;




	return 0;
}

10. 喜欢的数(2018研究生上机测试)

11. 字符串排序(2018研究生上机测试)

12. 充实的寒假生活(2018研究生上机测试)

难的的后面的简单题

#include <iostream>
#include<string>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
struct element
{
	int start;
	int end;
	bool operator <(const element&e)
	{
		return end < e.end;
	}
}elements[10001];

int main()
{
	int testNum;
	cin >> testNum;
	for (int i = 0; i < testNum; i++)
	{
		cin >> elements[i].start >> elements[i].end;
	}
	sort(elements, elements + testNum);
	int ans = 0;
	int right = -1;
	for (int i = 0; i < testNum; i++) {
		if (right < elements[i].start) {
			ans++;
			right = elements[i].end;
		}
	}
	cout << ans << endl;
	return 0;

	
}

13. 蜜蜂(2018研究生上机测试)

14. 因子分解(2017研究生推免上机考试)

这题说难不难,说简单也不简单

#include <iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

vector<int> numbers;

bool isPrime(int value)
{
	if (value == 1)
		return false;
	if (value == true)
		return true;
	for (int i = 2; i <= sqrt(value); i++)
	{
		if (value%i == 0)
			return false;
	}
	return true;
}

void getNumbers(int value)
{
	if (isPrime(value))
	{
		numbers.push_back(value);
	}
	for (int i = 2; i <= sqrt(value); i++)
	{
		if (value%i == 0)
		{
			int value1 = i;
			int value2 = value / i;
			if (!isPrime(value1))
				getNumbers(value1);
			else
				numbers.push_back(value1);
			if (!isPrime(value2))
				getNumbers(value2);
			else
				numbers.push_back(value2);
			return;
		}
	}
}
int main()
{
	int value;
	cin >> value;
	getNumbers(value);
	if (numbers.size() == 1)
	{
		cout << numbers[0];
		return 0;
	}
	sort(numbers.begin(), numbers.end());
	int last = numbers[0];
	int count = 1;
	bool flag = false;
	for (int i = 1; i < numbers.size(); i++)
	{
		if (numbers[i] == last)
		{
			count++;
		}
		else
		{
			if (count > 1)
			{
				flag = true;
				cout << last << "^" << count;
				count = 1;
			}
			else
			{
				if (flag)
					cout << "*" << last;
				else
					cout << last;
				flag = true;
			}
		}
		last = numbers[i];
	}
	if (count > 1)
	{
		if (flag)
			cout << "*" << last << "^" << count;
		else
			cout << last << "^" << count;

	}
	else
	{
		cout << "*" << last;

	}



	return 0;
}

14. ISBN号码(2017研究生推免上机考试)

15. 肿瘤检测

16. 回文素数(2017研究生推免上机考试)

深搜

1. 马走日(2019信科研究生上机测试)

2. The die is cast(2018计算机学科夏令营上机考试)

 

算是比较简单,经典的深搜了,把题目读懂难度更大。

#include <iostream>
#include<string>
#include <algorithm>
#include<map>
#include<vector>
#include<iterator>
using namespace std;
int m, n;
int countX = 0;

void dfsX(vector<vector<char>> &graph, vector<vector<bool>> &visited, int curX, int curY);
void dfsStar(vector<vector<char>> &graph, vector<vector<bool>> &visited, int curX, int curY);

void dfsX(vector<vector<char>> &graph, vector<vector<bool>> &visited, int curX, int curY)
{
	if (curX < 0 || curX >= n || curY < 0 || curY >= m || visited[curX][curY] || graph[curX][curY] == '.'||graph[curX][curY]=='*')
	{
		return;
	}
	visited[curX][curY] = true;
	dfsX(graph, visited, curX - 1, curY);
	dfsX(graph, visited, curX + 1, curY);
	dfsX(graph, visited, curX, curY - 1);
	dfsX(graph, visited, curX, curY + 1);

}

void dfsStar(vector<vector<char>> &graph, vector<vector<bool>> &visited, int curX, int curY) {
	if (curX < 0 || curX >= n || curY < 0 || curY >= m||visited[curX][curY]||graph[curX][curY]=='.')
	{
		return;
	}
	if (graph[curX][curY] == 'X')
	{
		countX++;
		dfsX(graph, visited, curX, curY);
		//return;
	}
	visited[curX][curY] = true;

	dfsStar(graph, visited, curX-1, curY);
	dfsStar(graph, visited, curX+1, curY);
	dfsStar(graph, visited, curX, curY-1);
	dfsStar(graph, visited, curX, curY+1);
		

}

int main()
{
	int count = 1;

	while (true)
	{
		vector<int> result;
		cin >> m >> n;
		if (m == 0 && n == 0)
			break;
		vector<string> strings;
		for (int i = 0; i < n; i++)
		{
			string s;
			cin >> s;
			strings.push_back(s);
		}
		vector<vector<char>> graph;
		vector<vector<bool>> visited;
		for (int i = 0; i < n; i++)
		{
			graph.push_back(vector<char>(m));
			visited.push_back(vector<bool>(m));
		}
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				graph[i][j] = strings[i][j];
				visited[i][j] = false;
			}
		}

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				if (graph[i][j] == '*'&&!visited[i][j])
				{
					dfsStar(graph, visited, i, j);
					if(countX>0)
					    result.push_back(countX);
					countX = 0;
				}
			}
		}
		sort(result.begin(), result.end());
		cout << "Throw " << count << endl;
		for (int i = 0; i < result.size(); i++)
		{
			cout << result[i] << " ";
		}
		cout << endl;
		cout << endl;
		count++;
	}

	return 0;
}

3. 逃离迷宫(2018大数据研究中心)

#include <iostream>
#include<string>
#include<queue>
using namespace std;

int testNum;
char matrix[11][11];
bool visited[11][11];
int distances[11][11];
int m, T;

struct point { int x; int y; };

point visit(int x, int y, int lastX, int lastY)
{
	point p;
	if (x < 0 || x >= m || y < 0 || y >= m||visited[x][y]||matrix[x][y]=='#')
	{
		p.x = -1;
		p.y = -1;
		return p;
	}
	visited[x][y] = true;
	distances[x][y] = distances[lastX][lastY] + 1;
	p.x = x;
	p.y = y;
	return p;
}
int main()
{
	cin >> testNum;
	for (int l = 0; l < testNum; l++)
	{
		int xS, yS;
		int xE, yE;
		cin >> m >> T;
		for (int i = 0; i < m; i++)
		{
			string s;
			cin >> s;
			for (int j = 0; j < m; j++)
			{
				matrix[i][j] = s[j];
				visited[i][j] = false;
				distances[i][j] = -1;
				if (s[j] == 'S')
				{
					xS = i;
					yS = j;
				}
				if (s[j] == 'E')
				{
					xE = i;
					yE = j;
				}
			}
		}
		queue<point>q;
		point S;
		S.x = xS;
		S.y = yS;
		point E;
		E.x = xE;
		E.y = yE;
		distances[S.x][S.y] = 0;
		visited[S.x][S.y] = true;
		q.push(S);
		while (!q.empty())
		{
			point cur = q.front();
			q.pop();
			if (cur.x == E.x&&cur.y == E.y)
			{
				break;
			}
			int curX = cur.x;
			int curY = cur.y;
			point p1 = visit(curX + 1, curY, curX, curY);
			point p2 = visit(curX - 1, curY, curX, curY);
			point p3 = visit(curX, curY + 1, curX, curY);
			point p4 = visit(curX, curY - 1, curX, curY);
			point ps[4];
			ps[0] = p1;
			ps[1] = p2;
			ps[2] = p3;
			ps[3] = p4;
			for (int k = 0; k < 4; k++)
			{
				if (ps[k].x != -1)
				{
					q.push(ps[k]);
				}
			}
		}
		if (distances[E.x][E.y] == -1 || distances[E.x][E.y] > T)
			cout << "NO" << endl;
		else
			cout << "YES" << endl;
	}
	
}

动态规划

1. jumping cows (2019信科研究生上机测试)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[151000][2];
int maxd(int a,int b)
{
    return a<b?b:a;
}
int main()
{
    int n,i,t;
    while (scanf("%d",&n) != EOF)
    {
        dp[0][0]=0;
        dp[0][1]=0;
        for (i=1; i<=n; i++)
        {
            scanf("%d",&t);
            dp[i][0]=maxd(dp[i-1][0],dp[i-1][1]-t);
            dp[i][1]=maxd(dp[i-1][1],dp[i-1][0]+t);
        }
        printf("%d\n",maxd(dp[n][0],dp[n][1]));
    }
}

2. A Mini Locomotive

动态规划真心看不懂

https://blog.csdn.net/y1356998843/article/details/81413667

3. Euro Efficiency(2018计算机学科夏令营上机考试)

动态规划,完全背包,以后有机会再看吧~

https://blog.csdn.net/wyjwyl/article/details/48395099

 

4. 动态规划必考,考一道跪一道

https://blog.csdn.net/sdj222555/article/details/8241432

5. real way tickets(2017研究生推免上机考试)

https://blog.csdn.net/da_kao_la/article/details/79624904

6. 怪盗基德的滑翔翼(2017计算机学科夏令营上机考试)

折腾了这么久,为数不多的能看懂的动态规划。

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
using namespace std;


int main()
{
	
	
		int testNum;
	cin >> testNum;

	for (int i = 0; i < testNum; i++)
	{
		int n;
		int result = -1;
		int result2 = -1;
		cin >> n;
		vector<int> values(n);
		vector<int> dp(n);
		vector<int> dp2(n);
		for (int j = 0; j < n; j++)
		{
			cin >> values[j];
		}
		for (int j = 0; j < n; j++)
		{
			dp[j] = 1;
			for (int k = 0; k < j; k++)
			{
				if (values[k] < values[j]&& dp[k] + 1>dp[j])
				{
					dp[j] = dp[k] + 1;
				}
			}
			result = max(result, dp[j]);
		}

		for (int j = 0; j < n; j++)
		{
			dp2[j] = 1;
			for (int k = 0; k < j; k++)
			{
				if (values[k] > values[j] && dp2[k] + 1>dp2[j])
				{
					dp2[j] = dp2[k] + 1;
				}
			}
			result2 = max(result, dp2[j]);
		}

		cout << max(result, result2) << endl;

	}




	return 0;
}

7. 开餐馆(2017大数据研究中心夏令营上机考试)

这个题和最长上升子序列是一个样子唉。

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
using namespace std;



int main()
{
	int testNum;
	cin >> testNum;	
	for (int i = 0; i < testNum; i++)
	{
		int n, k;
		cin >> n >> k;
		vector<int> dis;
		vector<int> values;
		for (int j = 0; j < n; j++)
		{
			int d;
			cin >> d;
			dis.push_back(d);
		}
		for (int j = 0; j < n; j++)
		{
			int v;
			cin >> v;
			values.push_back(v);
		}
		vector<int> dp(n);
		int ans = 0;
		for (int j = 0; j < n; j++)
		{
			dp[j] = values[j];
			for (int l = 0; l < j; l++)
			{
				if (dis[j] - dis[l] > k)
				{
					dp[j] = max(dp[j], dp[l] + values[j]);
				}

			}
			ans = max(dp[j], ans);
		}
		cout << ans << endl;
	}

	return 0;
}

图相关的算法

1. the suspects(2019年信科研究生上机测试)

并查集,重点啊!

#include <iostream>
#include <stdio.h>
using namespace std;
#define MAXN 30010 
int sum[MAXN];    //集合总数
int ufs[MAXN];    //并查集

void Init(int n)    //初始化
{
    int i;
    for(i=0;i<n;i++){
        ufs[i] = i;
        sum[i] = 1;
    }
}

int GetRoot(int a)    //获得a的根节点。路径压缩
{
    if(ufs[a]!=a){    //没找到根节点
        ufs[a] = GetRoot(ufs[a]);
    }
    return ufs[a];
}

void Merge(int a,int b)    //合并a和b的集合
{
    int x = GetRoot(a);
    int y = GetRoot(b);
    if(x!=y){
        ufs[y] = x;
        sum[x] += sum[y];
    }
}

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        if(n==0 && m==0) break;
        Init(n);    //初始化并查集
        while(m--){    //读入m行
            int t,one,two;
            scanf("%d",&t);    //每一行有t个数需要输入
            scanf("%d",&one);
            t--;
            while(t--){
                scanf("%d",&two);
                Merge(one,two);    //合并集合
            }
        }
        printf("%d\n",sum[GetRoot(0)]);
    }
    return 0;
}

2. Stockbroker Grapevine(2019年信科研究生上机测试)(最短路径Floyd算法)

#include <iostream>
using namespace std;

int dis[105][105];
int N,n,res,sum;
void init()
{
    for(int i=0;i<105;i++)
        for(int j=0;j<105;j++)
            if(i-j)dis[i][j]=1005;
            else dis[i][j]=0;
}
void flody()
{
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
        for(int k=1;k<=N;++k)
        dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
}
bool cal()
{
        sum=1005;
        for(int i=1;i<=N;i++)
        {
            int tmp=0,flag=0;
            for(int j=1;j<=N;j++)
            {
                if(i!=j&&(dis[i][j]<1005||dis[j][i]<1005))flag=1;//判断有没有孤立节点
                if(dis[i][j]>tmp)             tmp=dis[i][j];//求出最大值
            }
            if(!flag) return false;
            if(sum>=tmp)
            {//求出最大值的最小值
                res=i;
                sum=tmp;
            }
        }
        return true;
}
int main()
{
    while(cin>>N&&N)
    {
        init();
        for(int i=1;i<=N;++i)
        {
            cin>>n;
            for(int j=0;j<n;++j)
            {
                int t,d;
                cin>>t>>d;
                dis[i][t]=d;
            }
        }
        flody();
        if(cal())cout<<res<<" "<<sum<<endl;
        else cout<<"disjoint"<<endl;
    }
}

3. A Bug's Life 稍微难一点的并查集(2018研究生推免上机考试)

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<queue>
using namespace std;
const int MAXN = 2010;
int ranks[MAXN], pre[MAXN];
bool flag = true;
int find(int x)
{
	if (x != pre[x])
	{
		int px = find(pre[x]);
		ranks[x] = (ranks[x] + ranks[pre[x]]) % 2;
		pre[x] = px;
	}
	return pre[x];
}

int un(int x, int y) {
	int px = find(x);
	int py = find(y);
	if (px == py) {
		if ((ranks[x] + ranks[y]) % 2 == 0) { 
			return 1;
		}
		else {
			return 0;
		}
	}
	else {
		pre[py] = px; 
		ranks[py] = (ranks[x] + ranks[y] + 1) % 2; 
	}
	return 0;
}

int main()
{
	int num;
	cin >> num;

	for (int i = 0; i < num; i++)
	{
		for (int j = 0; j <= num; j++)
		{
			ranks[j] = 0;
			pre[j] = j;
		}
		int bugsNum, interactions;
		cin >> bugsNum >> interactions;
		vector<int> bugs(bugsNum+1,-1);
		for (int j = 0; j < interactions; j++)
		{
			int value1, value2;
			cin >> value1 >> value2;
			if (un(value1, value2) == 1)
			{
				flag = false;
				break;
			}
		}
		if (flag)
			cout << "Scenario #"<<i+1<<":"<<endl<<"No suspicious bugs found!" << endl;
		else
			cout << "Scenario #" << i+1 << ":" << endl << "Suspicious bugs found!" << endl;
		flag = true;


	}
	
	return 0;
}

 

4. 丛林中的路(2016年计算机学科夏令营考试)

最小生成树,重点中的重点!!!

(1)Prim

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
#include<map>
#include<stack>
using namespace std;
int graph[51][51];

int main()
{
	while (true)
	{
		int graph[27][27];
		int points;
		cin >> points;
			
		if (points == 0)
			break;
		for (int i = 0; i <= points; i++)
		{
			for (int j = 0; j <= points; j++)
			{
				graph[i][j] = 10000000;
			}
		}
		for (int i = 0; i < points-1; i++)
		{
			char p;
			int num;
			cin >> p >> num;;
			int start = p - 'A' + 1;
			for (int j = 0; j < num; j++)
			{
				char end;
				int dis;
				cin >> end >> dis;
				int endNum = end - 'A' + 1;
				graph[start][endNum] = dis;
				graph[endNum][start] = dis;
			}
		}
		vector<bool> visited(points+1, false);
		vector<int> distances(points+1,10000000);
		distances[1] = 0;
		for (int i = 1; i <= points; i++)
		{
			int cur = 0;
			for (int j = 1; j <= points; j++)
			{
				if (!visited[j]&&distances[j] < distances[cur])
				{
					cur = j;
				}
			}
			visited[cur] = true;
			for (int j = 1; j <= points; j++)
			{
				if (!visited[j] && graph[cur][j] < distances[j])
				{
					distances[j] = graph[cur][j];
				}
			}
		}
		int res = 0;
		for (int i = 1; i <= points; i++)
		{
			res += distances[i];
		}
		cout << res << endl;

	}
	return 0;
}

 

(2)使用并查集的算法

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
#include<map>
#include<stack>
using namespace std;

int ufs[27];
int sum[27];

void init() {
	for (int i = 0; i < 27; i++)
	{
		ufs[i] = i;
		sum[i] = 1;
	}
}
int find(int i) {
	if (ufs[i] != i)
	{
		i = find(ufs[i]);
	}
	return ufs[i];
}

void merge(int p1, int p2)
{
	int x = find(p1);
	int y = find(p2);

	if (x != y)
	{
		ufs[y] = x;
		sum[x] += sum[y];
	}
}

bool connect(int p1, int p2)
{
	return find(p1) == find(p2);
}

struct Edge {
	int start;
	int end;
	int dis;

	bool operator<(const Edge& e)
	{
		return dis < e.dis;
	}
};


int main()
{
	while (true)
	{
		init();
		int points;
		vector<Edge> edges;
		cin >> points;

		if (points == 0)
			break;
		for (int i = 0; i < points - 1; i++)
		{
			char p;
			int num;
			cin >> p >> num;;
			int start = p - 'A' + 1;
			for (int j = 0; j < num; j++)
			{
				char end;
				int dis;
				cin >> end >> dis;
				int endNum = end - 'A' + 1;
				Edge e;
				e.start = start;
				e.end = endNum;
				e.dis = dis;
				edges.push_back(e);
			}
		}
		sort(edges.begin(), edges.end());
		int counter = 0;
		int index = 0;
		int res = 0;
		while (counter < points - 1)
		{
			Edge e = edges[index];
			if (!connect(e.start, e.end))
			{
				merge(e.start, e.end);
				res += e.dis;
				counter++;
			}
			index++;
		}
		cout << res << endl;
	}
	return 0;
}

3. sort it all out 拓扑排序

#include <iostream>
#include<string>
#include<stack>
#include<queue>
#include<vector>
using namespace std;

int Sort[105];
int pos = 0;
int in[105], tmp[105];

bool find(vector<vector<int>> graph,int u,int v)
{
	vector<int> values = graph[u];
	for (int i = 0; i < values.size(); i++)
	{
		if (values[i] == v)
			return true;
	}
	return false;
}

int topoSort(queue<int>q,vector<vector<int>>G, int n) {
	while (!q.empty())q.pop();
	for (int i = 0; i < n; ++i)if (in[i] == 0) {
		q.push(i);
	}
	pos = 0;
	bool unSure = false;
	while (!q.empty()) {
		if (q.size() > 1) unSure = true;
		int t = q.front();
		q.pop();
		Sort[pos++] = t;
		for (int i = 0; i < G[t].size(); ++i) {
			if (--in[G[t][i]] == 0)
				q.push(G[t][i]);
		}
	}
	if (pos < n) return 1;
	if (unSure)  return 2;
	return 3;
}

int main()
{
	int result = 0;
	while (true)
	{
		for (int i = 0; i < 26; i++)
		{
			in[i] = 0;
			tmp[i] = 0;
		}
		int n, m;
		cin >> n >> m;
		if (n == 0 && m == 0)
			break;
		vector<vector<int>> graph(n);
		for (int i = 0; i < m; i++)
		{
			string s;
			cin >> s;
			if (result == 1 || result == 3)
				continue;
			int first = s[0]-'A';
			char oper = s[1];
			int second = s[2]-'A';
			if (oper == '<'&&!find(graph,first,second))
			{
				graph[first].push_back(second);
				in[second]++;
			}
			else if(oper == '>' && !find(graph, second, first))
			{
				graph[second].push_back(first);
				in[first]++;
			}
			queue<int>q;
			for (int i = 0; i < n; i++)
				tmp[i] = in[i];
			result = topoSort(q, graph, n);
			for (int i = 0; i < n; i++)
				in[i] = tmp[i];
			if (result == 3)
			{
				cout << "Sorted sequence determined after "<<i+1<<" relations: ";
				for (int i = 0; i < n; i++)
				{
					char c = Sort[i] + 'A';
					cout << c;
				}
				cout << "." << endl;
			}
			else if (result == 1)
			{
				cout <<"Inconsistency found after "<<i+1<<" relations." << endl;
			}
			
		}
		if(result==2)
		    cout << "Sorted sequence cannot be determined." << endl;
		result = 0;


	}
	return 0;


}

4. Prime Path(2017研究生推免上机考试)

这也是一个最短路径问题,基于BFS的最短路径问题。

https://blog.csdn.net/zck921031/article/details/7690428

 

5. Subway(2017计算机学科夏令营上机考试)

最短路径Dijkstra算法,这个题有点复杂,后面找到更典型的题目上代码。

 

 

 

考察STL的使用

1. 热血格斗场(2018研究生推免上机考试)

#include <iostream>
#include<string>
#include <algorithm>
#include<map>
using namespace std;


map<int, int> members;

int main()
{
	int num;
	cin >> num;
	members.insert(pair<int, int>(1000000000, 1));
	map<int, int>::iterator iter;
	for (int i = 0; i < num; i++)
	{
		int id, strength;
		cin >> id >> strength;
		iter = members.upper_bound(strength);
		if (iter == members.end())
		{
			iter--;
			cout << id << " " << iter->second << endl;
		}
		else if (iter == members.begin())
		{
			cout << id << " " << iter->second << endl;
		}
		else
		{
			int id1 = iter->second;
			int tmp1 = iter->first - strength;
			iter--;
			int id2 = iter->second;
			int tmp2 = strength - iter->first;
			if (tmp1 < tmp2)
			{
				cout << id << " " << id1 << endl;
			}
			else
			{
				cout << id << " " << id2 << endl;
			}
		}
		members.insert(pair<int, int>(strength, id));
	}
	
	
	return 0;
}

2. n-gram串频统计(2018年北京大学软件工程学科夏令营上机考试)

#include <iostream>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<map>
using namespace std;

int find(vector<string>v,string target)
{
	for (int i = 0; i < v.size(); i++)
	{
		if (target == v[i])
			return i;
	}
	return -1;
}

int main()
{
	int n;
	string s;
	vector<string> output(501,"");
	vector<string> origin;
	map<string, int>m;
	int maxF = 1;
	cin >> n;
	cin >> s;
	int len = s.length();
	for (int i = 0; i <= len - n; i++)
	{
		string tmp = s.substr(i, n);

		auto iter = m.find(tmp);
		if (iter == m.end())
		{
			m.insert(pair<string, int>(tmp, 1));
			origin.push_back(tmp);
		}
		else
		{
			iter->second++;
			if (iter->second > maxF)
			{
				maxF = iter->second;
			}
		}
	}
	auto iterator = m.begin();
	while (iterator != m.end())
	{
		if (iterator->second == maxF)
		{
			int index = find(origin, iterator->first);
			output[index]= iterator->first;
		}
		iterator++;
	}
	if (maxF == 1)
	{
		cout << "NO" << endl;
	}
	else
	{
		cout << maxF << endl;
		for (int i = 0; i < n; i++)
		{
			if(output[i]!="")
			    cout << output[i] << endl;
		}
	}
	return 0;


}

3. 最小堆(2017计算机学科夏令营上机考试)

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
using namespace std;



int main()
{
	int n;
	cin >> n;
	priority_queue<int, vector<int>, greater<int> > c; // 最小堆
	for (int i = 0; i < n; i++)
	{
		int type;
		cin >> type;
		if (type == 1)
		{
			int num;
			cin >> num;
			c.push(num);
		}
		else
		{
			int value = c.top();
			c.pop();
			cout << value << endl;
		}
	}


	return 0;
}

4. 双队列(2017大数据研究中心夏令营上机考试)

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
using namespace std;

struct Element {
	int num;
	int p;
	Element(int n2, int p2)
	{
		num = n2;
		p = p2;
	}

	bool operator <(const Element &e) const
	{
		return p < e.p;
	}
};

int main()
{
	set<Element> s;
	while (true)
	{
		int type;
		cin >> type;
		if (type == 0)
			break;
		else if (type == 1)
		{
			int n, p;
			cin >> n >> p;
			s.insert(Element(n, p));
		}
		else if (type == 2)
		{
			if (s.empty())
			{
				cout << 0 << endl;
			}
			else
			{
				set<Element>::iterator it = s.end();
				it--;
				cout << (*it).num << endl;
				s.erase(*it);
			}
		}
		else if (type == 3)
		{
			if (s.empty())
			{
				cout << 0 << endl;
			}
			else
			{
				set<Element>::iterator it = s.begin();
				cout << (*it).num << endl;
				s.erase(*it);
			}
		}
	}

	return 0;
}

5. 奖学金(2017研究生上机测试)

考察类的排序

https://www.cnblogs.com/tangmiao/p/10200987.html

大型枚举或模拟

1. Word-Search Wonder(2018年北京大学软件工程学科夏令营上机考试)

这个没通过,没找到原因啊,不知道哪个细节写错了

#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<math.h>
#include<queue>
#include <cstring>
#include<set>
#include<map>
#include<stack>
using namespace std;
char matrix[101][101];
int startX = -1;
int startY = -1;
int endX = -1;
int endY = -1;
int l;
void search(int x, int y, string word)
{
	bool flag = true;
	if (x + 1 - word.length() >= 0)
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x - i][y] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x - word.length() + 1;
		endY = y;
		return;
	}
	flag = true;
	if (y + 1 - word.length() >= 0)
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x][y-i] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x;
		endY = y - word.length() + 1;
		return;
	}
	flag = true;
	if (l-x >= word.length())
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x+i][y] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x+word.length()-1;
		endY = y;
		return;
	}
	flag = true;
	if (l - y >= word.length())
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x][y+i] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x;
		endY = y + word.length() - 1;
		return;
	}

	flag = true;
	if (x + 1 - word.length() >= 0 && y + 1 - word.length() >= 0)
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x - i][y-i] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x - word.length() + 1;
		endY = y - word.length() + 1;
		return;
	}

	flag = true;
	if (l - x >= word.length() && y + 1 - word.length() >= 0)
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x + i][y - i] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x + word.length() - 1;
		endY = y - word.length() + 1;
		return;
	}

	flag = true;
	if (l - x >= word.length() && l-y >= word.length())
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x + i][y + i] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x + word.length() - 1;
		endY = y + word.length() - 1;
		return;
	}

	flag = true;
	if (x + 1 - word.length() >= 0 && l - y >= word.length())
	{
		for (int i = 0; i < word.length(); i++)
		{
			if (matrix[x-i][y + i] != word[i])
			{
				flag = false;
				break;
			}
		}
	}
	if (flag)
	{
		startX = x;
		startY = y;
		endX = x - word.length() + 1;
		endY = y + word.length() - 1;
		return;
	}


}
int main()
{
	cin >> l;
	for (int i = 0; i < l; i++)
	{
		string tmp;
		cin >> tmp;
		for (int j = 0; j < l; j++)
		{
			matrix[i][j] = tmp[j];
		}
	}
	while (true)
	{
		string word;
		cin >> word;
		if (word == "0")
			break;
		bool flag = false;
		for (int i = 0; i < l; i++)
		{
			for (int j = 0; j < l; j++)
			{
				if (matrix[i][j] == word[0])
				{
					search(i, j, word);
					if (startX != -1)
					{
						cout << startX + 1 << "," << startY + 1<<" ";
						cout << endX + 1 << "," << endY + 1 <<endl;
						flag = true;
						startX = -1;
						startY = -1;
						endX = -1;
						endY = -1;
						break;
					}
				}
				
			}
			if (flag)
				break;
		}
		if (!flag)
		{
			cout << "Not found" << endl;
		}
	}
	return 0;
}

2. 生存游戏(2017大数据研究中心夏令营上机考试)

这个问题很经典,leetcode上有。

  • 12
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值