2018年长沙理工大学第十三届程序设计竞赛

A LL

“LL是什么?这都不知道的话,别说自己是程序猿啊!”
  “longlong?”
  “。。。肯定是LoveLive啊!”
  qwb为了检验你是否是真正的程序猿,决定出道题考考你:现在程序会输入一行字符串,如果恰好是lovelive(不区分大小写)就输出yes,否则输出no。

输入描述:

输入有多组(组数不超过100),每组输入一行字符串(字符串长度不超过100)。

输出描述:

输出占一行,如果输入符合要求则输出yes,否则输出no。
示例1

输入

longlong
LoveLive
love live

输出

no
yes
no


签到题
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
char str[110];
int main() {
	while(gets(str)) {
		int len = strlen(str);
		bool flag = false;
		if(len == 8) {
			if(str[0] =='L' || str[0] == 'l')
			if(str[1] =='o' || str[1] == 'O')
			if(str[2] =='v' || str[2] == 'V')
			if(str[3] =='e' || str[3] == 'E')
			if(str[4] =='L' || str[4] == 'l')
			if(str[5] =='i' || str[5] == 'I')
			if(str[6] =='V' || str[6] == 'v')
			if(str[7] =='e' || str[7] == 'E')
				flag = true;
		}
		if(flag) printf("yes\n");
		else printf("no\n");
	}
	return 0;
}

  

B 奇怪的加法

题目描述

zhrt是数学大佬,但有一天一道奇怪的数学题把他难住了:题目要求计算两个十进制数相加后的结果,但在本题中是不需要进位的!
  现在zhrt弯下他的小蛮腰向你请教,你能帮帮他吗?

输入描述:

输入有多组(组数不超过1000),每组占一行,每行有2个正整数A和B。(A,B<=1e9)

输出描述:

每组输出占一行,输出题目中A和B相加的结果。
示例1

输入

123 321
999 1
99 11

输出

444
990
0

模拟题,做加法运行,不进位就行。
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
char str1[11], str2[11], str3[11];

void solve() {
	int len1 = strlen(str1)-1;
	int len2 = strlen(str2)-1;
	int len3 = 0;
	while(len1 >= 0 && len2 >= 0) {
		int ans = str1[len1] - '0' + str2[len2] - '0';
		ans %= 10;
		str3[len3++] = ans+'0';
		len1--;len2--;
	}
	while(len1 >= 0) str3[len3++] = str1[len1--]; 
	while(len2 >= 0) str3[len3++] = str2[len2--]; 
	for(int i = 0; i < len3/2; i ++) {
		swap(str3[i],str3[len3-1-i]);
	}
	int i = 0;
	while(str3[i] == '0')i++;
	if(i == len3) printf("0");
	for(; i < len3; i ++) {
		printf("%c",str3[i]);
	}
	printf("\n");
}
int main() {
	while(cin >> str1 >> str2) {
		solve();
		memset(str1,0, sizeof(str1));
		memset(str2,0, sizeof(str2));
		memset(str3,0, sizeof(str3));
	}
	return 0;
}

  

C 取手机

题目描述

durong有a台iphonex和b台s8,并且放在一个保险箱里,durong现在一台一台从保险箱随机拿出这些手机,现在他想知道第k次拿出s8的概率是多少

输入描述:

第一行一个正整数T,表示数据组数。(1<=T<=10000)
接下来T行输入a,b,k
其中(1<=a,b,k<=1e9) k<=a+b;

输出描述:

第k次拿出s8的概率,保留三位小数
示例1

输入

1
1 1 1

输出

0.500

概率率,概率为b(a+b)

#include <iostream>
#include <stdio.h>
#include <algorithm>
#define ll long long
using namespace std;
int a, b, k;
void solve() {
	printf("%.3f\n",1.0*b/(a+b));
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> a >> b >> k;
		solve();
	}
	return 0;
}

  

E 小木乃伊到我家

题目描述

  AA的欧尼酱qwb是个考古学家,有一天qwb发现了只白白圆圆小小的木乃伊,它是个爱哭鬼却很努力。qwb想把这么可爱的小木乃伊送给
AA,于是便找上了快递姐姐,这下可让快递姐姐犯愁了,因为去往AA家的路实在太难走了(甚至有可能没有路能走到AA家),快递姐姐
找上聪明的ACMer,想请你帮忙找出最快到达AA家的路,你行吗?

输入描述:

第一行输入两个整数n和m(2<=n<=m<=200000),分别表示有n座城市和m条路,城市编号为1~n(快递姐姐所在城市为1,AA所在城市为n)。
接下来m行,每行输入3个整数u,v,w(u,v<=n,w<=100000),分别表示城市u和城市v之间有一条长为w的路。

输出描述:

输出结果占一行,输出快递姐姐到达AA家最短需要走多远的路,如果没有路能走到AA家,则输出“qwb baka”(不用输出双引号)。
示例1

输入

4 4
1 2 1
2 3 2
3 4 3
2 3 1

输出

5

最短路径模板题,dijistra算法就可以过。
#include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 200010;
typedef pair<int,int> P;
struct Nod {
	int to, cost;
};
vector<Nod> vs[N];
int d[N];
void dij(int s) {
	priority_queue<P, vector<P>, greater<P> > que;
	d[s] = 0;
	que.push(P(0,s));
	while(que.size()) {
		P p = que.top(); que.pop();
		int v = p.second;
		//printf("dsa\n");
		if(d[v] < p.first) continue;
		//cout << vs[v].size() << endl;
		for(int i = 0; i < vs[v].size(); i ++) {
			Nod e = vs[v][i];
			//cout << e.to << ' ' << e.cost << endl;
			if(d[e.to] > d[v] + e.cost) {
				d[e.to] = d[v] + e.cost;
				que.push(P(d[e.to],e.to));
			}
		}
	}
}
int main() {
	int n, m;
	cin >> n >> m;
	for(int i = 0; i <= n; i ++) d[i] = INF;
	for(int i = 0; i < m; i ++) {
		int u, v, w;
		cin >> u >> v >> w;
		Nod e;
		e.to = v; e.cost = w;
		vs[u].push_back(e);
		Nod ee;
		ee.to = u; ee.cost = w;
		vs[v].push_back(ee);
	}
	dij(1);
	//for(int i = 1; i <= n; i ++) cout << d[i] << ' ';
	//cout << endl;
	if(d[n] == INF) printf("qwb baka\n");
	else cout << d[n] << endl;
	return 0;
}

  

G 逃离迷宫

题目描述

给你一个n*m的图,地图上'.'代表可以走的地方,而'#'代表陷阱不能走,
'P'代表人物位置,'K'代表钥匙,'E'代表出口。人物一个,钥匙有多个,
('K'的数量<=50)),出口一个,每个位置可以向(上,下,左,右)四个
方向走一格,花费一个单位时间,现在你需要花费最少的时间拿到钥匙
然后从迷宫的出口出去(若没有钥匙,则不能进入迷宫出口所在的格子)。

输入描述:

第一行一个整数T(T <= 50),代表数据的组数
接下来一行n,m(n<=500,m<=500),代表地图的行和列
接下来n行,每行一个长度为m的字符串,组成一个图。

输出描述:

如果可以出去,输出所花费的最少时间。
如果不能出去,输出一行"No solution"。
示例1

输入

3
5 5
....P
##..E
K#...
##...
.....
5 5
P....
.....
..E..
.....
....K
5 5
P#..E
.#.#.
.#.#.
.#.#.
...#K

输出

No solution
12
No solution

bfs问题,用两个bfs,一个从P到所有的K,一个从E到所有的K。用map保存。然后在求最短的那个路径。
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int t, n, m, gx, gy, xx, yy;
const int N = 550;
char str[N][N];
int d[N][N];
int dx[] = {1,0,-1,0}, dy[] = {0, 1, 0, -1};
typedef pair<int, int> P;
map<P,int> mp1, mp2;
void bfs(int x1, int y1,int flag) {
	memset(d,-1,sizeof(d));
	queue<P> que;
	que.push(P(x1,y1));
	d[x1][y1] = 0;
	while(que.size()) {
		P p = que.front(); que.pop();
		for(int i = 0; i < 4; i ++) {
			int nx = dx[i] + p.first, ny = dy[i] + p.second;
			if(1 <= nx && nx <= n && 1 <= ny && ny <= m && str[nx][ny] != '#' && d[nx][ny] == -1) {
				if(flag && str[nx][ny] != 'E') {
					que.push(P(nx,ny));
					d[nx][ny] = d[p.first][p.second] + 1;
					if(str[nx][ny] == 'K') mp1[make_pair(nx,ny)] = d[nx][ny];
				} else if(!flag && str[nx][ny] != 'P') {
					que.push(P(nx,ny));
					d[nx][ny] = d[p.first][p.second] + 1;
					if(str[nx][ny] == 'K') mp2[make_pair(nx,ny)] = d[nx][ny];
				}
			}
		}
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin >> t;
	while(t--) {
		cin >> n >> m;
		memset(str,0,sizeof(str));
		mp1.clear();
		mp2.clear();
		for(int i = 1; i <= n; i ++) cin >> str[i] + 1;
		for(int i = 1; i <= n; i ++) {
			for(int j = 1; j <= m; j ++) {
				if(str[i][j] == 'P') {
					gx = i;
					gy = j;
				}
				if(str[i][j] == 'E') {
					xx = i;
					yy = j;
				}
			}
		}
		int MIN = INF;
		bfs(gx,gy,1);
		bfs(xx,yy,0);
		if(mp1.size()&&mp2.size()) {
			map<P,int> :: iterator it = mp1.begin();
			for(; it != mp1.end(); it++) {
				if(mp2.count((*it).first))
				MIN = min(MIN,(*it).second+mp2[(*it).first]);
			}
			printf("%d\n",MIN);
		} else printf("No solution\n",MIN);
	}
	return 0;
}

  

H 数学考试

题目描述

今天qwb要参加一个数学考试,这套试卷一共有n道题,每道题qwb能获得的分数为ai,qwb并不打算把这些题全做完,
他想选总共2k道题来做,并且期望他能获得的分数尽可能的大,他准备选2个不连续的长度为k的区间,
即[L,L+1,L+2,....,L+k-1],[R,R+1,R+2,...,R+k-1](R >= L+k)。

输入描述:

第一行一个整数T(T<=10),代表有T组数据
接下来一行两个整数n,k,(1<=n<=200,000),(1<=k,2k <= n)
接下来一行n个整数a1,a2,...,an,(-100,000<=ai<=100,000)

输出描述:

输出一个整数,qwb能获得的最大分数
示例1

输入

2
6 3
1 1 1 1 1 1
8 2
-1 0 2 -1 -1 2 3 -1

输出

6
7

输出

求两个不重叠区间之和的最大值。

sum[i] 表示ai+ai+1+...ai+k-1。用一个for遍历就可以了,每次求1-i之前的最大值假设sum[i+k]

#include <iostream>
#include <stdio.h>
#include <cstring>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
const int N = 2e5+10;
int n, k;
ll a[N], sum[N];

int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> k;
		a[0] = 0;
		for(int i = 1; i <= n; i ++) {
			cin >> a[i];
			a[i] += a[i-1];
		}
		for(int i = 1; i <= n-k+1; i ++) {
			sum[i] = a[i+k-1]-a[i-1];
		}
		ll MAX = -1e18;
		ll MAX1 = -1e18;
		for(int i = 1; i <= n-2*k+1; i ++) {
			if(sum[i] > MAX1) MAX1 = sum[i];
			if(MAX1 + sum[i+k] > MAX) MAX = MAX1 + sum[i+k];
		}
		cout << MAX << endl;
		memset(sum,0,sizeof(sum));
	}
	return 0;
}

  

L 仓鼠养殖计划

题目描述

集训队暑训的时候,是睡在机房的,有几个小伙子不甘寂寞,带了仓鼠来机房。有的还不止带了一只!
为此,贴心的集训队刘队长买了一大一小两种放仓鼠笼子的架子,大的可以放两个仓鼠笼 小的只能放一个。
要注意的是仓鼠是领地动物,一般来讲 仓鼠笼与仓鼠笼之间是不能贴在一起的,
但同一个人带来的仓鼠的仓鼠笼可以被放在一起(既两个仓鼠笼如果属于同一个人,那么这两个仓鼠笼就可以被放在同一个大架子上)
现在告诉你现有的两种架子的数量和多少人带了仓鼠以及每个人带的仓鼠的数量,问你是否能将这些仓鼠放下。

输入描述:

第一行为一个数T 表示测试样例组数

对于每组测试数据

第1行输入a,b,n; 分别为小架子的数量,大架子的数量,带了仓鼠的人数

第2行有n个数字P
1
-P
n
,分别表示每个人带的仓鼠的数量

输出描述:

如果放得下 则输出"Yes" 否则输出"No"
示例1

输入

1
1 2 4
1 1 1 1

输出

No

备注:

1<=n<=50 1<=a,b<=100  1<=Pi<=20
 
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int t, a, b, n;
int p[110];
int main() {
	cin >> t;
	while(t--) {
		cin >> a >> b >> n;
		for(int i = 0; i < n; i ++) {
			cin >> p[i];
		}
		bool flag = true;
		for(int i = 0; i < n; i ++) {
			while(p[i] > 1 && b > 0) {
				p[i] -= 2;
				b--;
			}
			while(p[i] > 0 && a > 0) {
				p[i]--;
				a--;
			}
			if(p[i] != 0) {
				flag = false;
				break;
			}
		}
		if(flag)printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

  

posted @ 2018-04-14 17:28  starry_sky  阅读(669)  评论(0编辑  收藏  举报