热身赛

题目分析

暴力美学专题

A:可以枚举区间[i, j] ,枚举区间的复杂度是O(n*n*n)

#include <cstdio>

typedef long long ll;
ll num[25];
char str[25];

int main(){
	int n;
	int t = 1;
	while(scanf("%d", &n) != EOF){
		for(int i = 0; i < n; ++i)	scanf("%lld", num+i);
		ll maxn = -1e18 - 10;
		for(int i = 0; i < n; ++i)
			for(int j = i; j < n; ++j){
				ll sum = 1;
				for(int k = i; k <= j; ++k)
					sum *= num[k];
				if(sum > maxn)	maxn = sum;
			}
		printf("Case #%d: The maximum product is %lld.\n\n", t++, maxn<0?0:maxn);
	}
	return 0;
}


B:暴力即可,加些技巧可简短代码长度

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int qq = (1<<10) + 10;
int tot, n;
int vis[15];

struct Num{
	int x, y;
	bool operator < (const Num &a)const{
		return y < a.y;
	}
}num[qq];

bool judge(int x){
	int flag[11];
	memset(flag, 0, sizeof(flag));
	int y = x / n;
	if(x < 10000)	flag[0] = 1;
	while(x){
		flag[x%10] = 1;
		x /= 10;
	}
	if(y < 10000 && y > 1000){
		if(flag[0])	return false;
		else	flag[0] = 1;
	}else if(y < 1000)	return false;
	while(y){
		if(flag[y%10]) return false;
		flag[y%10] = 1;
		y /= 10;
	}
	return true;
}

int main(){
	int t = 0;
	while(scanf("%d", &n)==1 && n){
		memset(vis, 0, sizeof(vis));
		tot = 0;
		if(t)	puts("");
		int cnt = 0;
		for(int i,j,k,l,m = 0; m < 10; ++m){
			vis[m] = 1;
			for(l = 0; l < 10; ++l){
				if(vis[l])	continue;
				vis[l] = 1;
				for(k = 0; k < 10; ++k){
					if(vis[k])	continue;
					vis[k] = 1;
					for(j = 0; j < 10; ++j){
						if(vis[j])	continue;
						vis[j] = 1;
						for(i = 0; i < 10; ++i){
							if(vis[i])	continue;
							int res = m*10000+l*1000+k*100+j*10+i;
							//printf("%d\n", res);
							//if(res == 96270)	printf("111\n");
							if(res % n == 0 && judge(res)){
								num[tot].x = res;
								num[tot++].y = res/n;
								cnt++;
							}
						}
						vis[j] = 0;
					}
					vis[k] = 0;
				}
				vis[l] = 0;
			}
			vis[m] = 0;
		}
		if(!cnt)	printf("There are no solutions for %d.\n", n);
		sort(num, num+tot);
		for(int i = 0; i < tot; ++i)
			printf("%05d / %05d = %d\n", num[i].x, num[i].y, n);
		t++;
	}
	return 0;
}



C:先把n + n以内的素数求出来,然后dfs从小到大去加数判断即可,注意最后要判断一下首尾

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cctype>
using namespace std;

const int qq = 50;
int prim[qq];
int n;
int num[qq];
int vis[qq];

void dfs(int cnt){
	if(cnt == n){
		if(!prim[num[0]+num[n-1]]){
			for(int i = 0; i < n-1; ++i)
				printf("%d ", num[i]);
			printf("%d\n", num[n-1]);
		}
		return;
	}
	for(int i = 1; i <= n; ++i){
		if(vis[i])	continue;
		if(prim[num[cnt-1]+i])	continue;
		vis[i] = 1;
		num[cnt] = i;
		dfs(cnt+1);
		vis[i] = 0;
	}
}

int main(){
	memset(prim, 0, sizeof(prim));
	prim[1] = 1;
	for(int i = 2; i < qq; ++i)
		for(int j = i+i; j < qq; j += i)
			prim[j] = 1;
	int t = 1;
	while(scanf("%d", &n) != EOF){
		if(t != 1)
			printf("\n");
		printf("Case %d:\n", t++);
		memset(vis, 0, sizeof(vis));
		vis[1] = 1;
		num[0] = 1;
		dfs(1);
	}
	return 0;
}


D:一道简单的树形结构题,从根节点一直向下dfs然后在搜索的过程都更新当前节点到根节点的距离即可,最后找一下每个节点到根节点的最大距离,存图需要用邻接表,这里用vector实现(推荐用静态链表(链式前向星))

PS:一般情况下vector的获得内存空间的实现要看评测既是否开了O2优化,开了的话能大大提高cache的命中率,从而提升使用vector的效率,如果没开O2的话很多情况下使用vector会超时

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define REP(i, x, n)	for(int i = x; i < n; ++i)
const int qq = 1e5 + 10;
vector<int> vt[qq],dist[qq];
LL dp[qq];
int n;
LL m;
void dfs(int u, LL w){
	dp[u] = w;
	int sz = (int)vt[u].size();
	for(int j = 0; j < sz; ++j){
		dfs(vt[u][j], w + dist[u][j]);
	}
}

int main(){
	int t;	cin >> t;
	while(t--){
		memset(dp, 0, sizeof(dp));
		scanf("%d%lld", &n, &m);
		for(int i = 0; i < n - 1; ++i){
			int a, b, c;	scanf("%d%d%d", &a, &b, &c);
			vt[a].pb(b), dist[a].pb(c);
		}
		dfs(1, 0);
		LL maxn = -1;
		for(int i = 1; i <= n; ++i)
			maxn = max(maxn, dp[i]);
		if(maxn < m)	printf("-1\n");
		else	printf("%lld\n", maxn);
		for(int i = 0; i <= n; ++i)
			vt[i].clear(), dist[i].clear();
	}
	return 0;
}


E:首先要明确,你要得到某个颜色一定是这个生物去吞噬了其他所有生物(或者其他生物吞噬其他生物,但是最终被这个颜色的生物吞噬了),这题是基于贪心的想法,先把生物的尺寸大小从大到小排序,用num[i]代表第i位置上生物的大小,sum[i]代表从i开始包括i到最后一个生物尺寸大小的和,那么如果存在某个 (num[i] + sum[i + 1])* 2  〈 num[i - 1], 那么之后的所有生物的颜色都不能得到了。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <sstream>
#include <iostream>
#include <algorithm>
 
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define REP(i, x, n)	for(int i = x; i < n; ++i)
const int qq = 1e5 + 10;
int n;
LL sum[qq], num[qq];
bool cmp(LL a, LL b){
	return a > b;
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
		scanf("%lld", num + i);
	sort(num + 1, num + 1 + n, cmp);
	for(int i = n; i >= 1; --i)
		sum[i] = sum[i + 1] + num[i];
	int res = 1;
	for(int i = 2; i <= n; ++i)
		if((LL)2 * (num[i] + sum[i + 1]) >= num[i - 1])	res++;
		else{
			break;
		}
	printf("%d\n", res);
	return 0;
}


F:暴力打表或者递归求解都可

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
#define LL long long
#define REP(i, x, n)	for(int i = x; i < n; ++i)
#define mst(Arr, x)	memset(Arr, x, sizeof(Arr))
const int qq = 23;
LL W[qq][qq][qq];
int a, b, c;
LL Dfs(int a, int b, int c){
	if(a <= 0 || b <= 0 || c <= 0)	return 1;
	if(a > 20 || b > 20 || c > 20){
		if(W[20][20][20] != -1)	return W[20][20][20];
		else	return Dfs(20, 20, 20);
	}
	if(W[a][b][c] != -1)	return W[a][b][c];
	if(a < b && b < c)
		return W[a][b][c] = Dfs(a, b, c - 1) + Dfs(a, b - 1, c - 1) - Dfs(a, b - 1, c);
	return W[a][b][c] = Dfs(a - 1, b, c) + Dfs(a - 1, b - 1, c) + Dfs(a - 1, b, c - 1) - Dfs(a - 1, b -1 , c - 1);
}
int main(){
	while(scanf("%d%d%d", &a, &b, &c) != EOF){
		mst(W, -1);
		if(a == -1 && b == -1 && c == -1)	break;
		printf("w(%d, %d, %d) = %lld\n", a, b, c, Dfs(a, b, c));
	}
	return 0;
}

G:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;
#define LL long long
#define REP(i, x, n)	for(int i = 0; i < n; ++i)
#define mst(Arr, x)	memset(Arr, x, sizeof(Arr))
#define pb push_back
const int qq = 23;
int C[qq][qq];
int vis[qq];
int n, maxn;
void Dfs(int u){
	if(u > n){
		int sum = 0;
		for(int i = 1; i <= n; ++i)
			if(vis[i]){
				for(int j = 1; j <= n; ++j)
					if(!vis[j])	sum += C[i][j];
			}
		maxn = max(maxn, sum);
		return;
	}
	vis[u] = 1;
	Dfs(u + 1);
	vis[u] = 0;
	Dfs(u + 1);
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			scanf("%d", &C[i][j]);
	maxn = -1;
	mst(vis, 0);
	Dfs(1);
	printf("%d\n", maxn);
	return 0;
}	



H题:二进制枚举搜索都可

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>

using namespace std;
#define REP(i, x, n)	for(int i = x; i < n; ++i)
const int qq = 6;
char gra[qq][qq], tmp[qq][qq];
int num[qq];
int n;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
bool isboard(int x, int y){
	if(x < 1 || y < 1 || x > n || y > n)	return false;
	return true;
}
int check(){
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			tmp[i][j] = gra[i][j];
	for(int col = 1; col <= n; ++col){
		for(int i = 0; i < n; ++i)
			if(num[col] & (1 << i)){
				if(tmp[col][i + 1] == 'X')	continue;
				tmp[col][i + 1] = '1';
			}
	}
	int cnt = 0;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j){
			if(tmp[i][j] == '1'){
				for(int k = 0; k < 4; ++k){
					int x = i + dx[k], y = j + dy[k];
					bool flag = true;
					while(1){
						if(!isboard(x, y))	break;
						if(tmp[x][y] == 'X')	break;
						if(tmp[x][y] == '1'){
							flag = false;
							break;
						}
						x = x + dx[k];
						y = y + dy[k];
					}
					if(!flag)	return false;
				}
				++cnt;
			}
		}
	return cnt;
}
int main(){
	while(scanf("%d", &n) != EOF){
		if(!n)	break;
		for(int i = 1; i <= n; ++i)
			scanf("%s", gra[i] + 1);
		int ans = 0;
		if(n == 4){
			for(int l, k, j, i = 0; i < (1 << n); ++i)
				for(j = 0; j < (1 << n); ++j)
					for(k = 0; k < (1 << n); ++k)
						for(l = 0; l < (1 << n); ++l){
							num[1] = i, num[2] = j, num[3] = k, num[4] = l;
							ans = max(check(), ans);
						}
		}else if(n == 3){
			for(int k, j, i = 0; i < (1 << n); ++i)
				for(j = 0; j < (1 << n); ++j)
					for(k = 0; k < (1 << n); ++k){
						num[1] = i, num[2] = j, num[3] = k;
						ans = max(check(), ans);
					}
		}else if(n == 2){
			for(int j, i = 0; i < (1 << n); ++i)
				for(j = 0; j < (1 << n); ++j){
					num[1] = i, num[2] = j;
					ans = max(check(), ans);
				}
		}else{
			if(gra[1][1] == '.')	ans = 1;
		}
		printf("%d\n", ans);
	}
	return 0;
}




I:思维题,需要分情况讨论,然后推公式

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define pb push_back
#define mk make_pair
#define LL long long
#define REP(i, x, n)	for(int i = x; i < n; ++i)
#define mst(Arr, x)	memset(Arr, x, sizeof(Arr))
const int qq = 1e5 + 10;
LL n, m;
bool check(LL x, LL k){
	LL sum = (1LL + x) * x / 2;
	if(k - sum <= 0)	return true;
	return false;
}

int main(){
	scanf("%lld%lld", &n, &m);
	if(n <= m){
		printf("%lld\n", n);
		return 0;
	}
	n -= m;
	n *= 2LL;
	LL d = sqrt(n);
	while(d * (d + 1) < n)	d++;
	printf("%lld\n", d + m);
	return 0;
}


J:思维

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>

using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 2e5 + 10;
int n, m, k;
struct Item{
	int a, b;
	bool operator < (const Item &it)const{
		return b - a > it.b - it.a;
	}
}item[qq];

int main(){
	scanf("%d%d", &n, &k);
	int cnt = 0;
	for(int i = 0; i < n; ++i)
		scanf("%d", &item[i].a);
	for(int i = 0; i < n; ++i){
		scanf("%d", &item[i].b);
		if(item[i].b < item[i].a)	cnt++;
	}
	sort(item, item + n);
	ll sum = 0;
	for(int i = 0; i < k; ++i)
		sum += item[i].a;
	int p;
	for(p = k; p < n; ++p)
		if(item[p].b - item[p].a >= 0)	sum += item[p].a;
		else	break;
	for( ; p < n; ++p)
		sum += item[p].b;
	printf("%lld\n", sum);
	return 0;
}



K: BFS + 优先队列

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define pill pair<int, int>
#define REP(i, x, n)	for(int i = x; i < n; ++i)
const int qq = 1e3 + 10;
const LL INF = 1e16;
LL route[43];
LL dist[qq][qq];
char gra[qq][qq];
int tx, ty;
int k, n, m;
LL val;
char op[10];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool check(int x, int y){
	if(x < 1 || y < 1 || x > n || y > m)
		return false;
	return true;
}
struct Node{
	int x, y;
	LL dis;
	bool operator < (const Node &c)const{
		return dis > c.dis;
	}
}tmp, now;
void bfs(){
	priority_queue<Node> Q;
	tmp.x = tx, tmp.y = ty;
	tmp.dis = 0;
	Q.push(tmp);
	while(!Q.empty()){
		now = Q.top(), Q.pop();
		if(now.x == 1 || now.x == n || now.y == 1 || now.y == m){
			printf("%lld\n", now.dis);
			return;
		}
		for(int i = 0; i < 4; ++i){
			int x = now.x + dx[i];
			int y = now.y + dy[i];
			if(!check(x, y))	continue;
			if(dist[now.x][now.y] + route[gra[x][y] - 'A'] < dist[x][y]){
				dist[x][y] = dist[now.x][now.y] + route[gra[x][y] - 'A'];
				tmp.dis = dist[x][y];
				tmp.x = x, tmp.y = y;
				Q.push(tmp);
			}
		}
	}
}
int main(){
	int t;	scanf("%d", &t);
	while(t--){
		scanf("%d%d%d", &k, &m, &n);
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= m; ++j)
				dist[i][j] = INF;
		for(int i = 0; i < k; ++i){
			scanf("%s%lld", op, &val);
			route[op[0] -'A'] = val;
		}
		for(int i = 1; i <= n; ++i){
			scanf("%s", gra[i] + 1);
			for(int j = 1; j <= m; ++j)
				if(gra[i][j] == 'E'){
					tx = i, ty = j;
				}
		}
		dist[tx][ty] = 0;
		bfs();
	}
	return 0;
}

/**********************************************************************
	Problem: 1815
	User: Yokile
	Language: C++
	Result: AC
	Time:10336 ms
	Memory:27060 kb
**********************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值