2021百度之星初赛三

1.数字游戏

给你最大值,最小值和平均值,判断是否能构成一个数组符合给定值
特判一下有没有最小值大于最大值的情况

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100;
int a[maxn];
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n, maxx, minn, aver;
        cin >> n >> maxx >> minn >> aver;
        if (maxx < minn) cout << "no" << endl;
        else if ((n == 1) &&( maxx == minn )&&( maxx == aver) )cout << "yes" << endl;
        else if (n == 1) cout << "no" << endl;
        else if (n == 2 && aver == 0 && maxx + minn == 0) cout << "yes" << endl;
        else if(n == 2 && aver == 0) cout << "no" << endl;
        else if(n==2&&((maxx+minn)%aver==0)&&((maxx+minn)/2==aver)) cout<<"yes"<<endl;
        else if (n == 2) cout << "no" << endl;
        else {
            double num1 = (n - 1)*maxx+minn ;
            double num2 = (n - 1)*minn+maxx ;
            double num3 = aver * (n);
            if (num3 >= num2 && num3 <= num1) {
                cout << "yes" << endl;
            }
            else {
                cout << "no" << endl;
            }
        }
    }
    return 0;
}

2.网格路径

判断从(1,1)到(n,n)的路径中有几条完全不相同的路(除了(1,1)和(n,n)可以重合)
那就只有三种可能,只有0,1,2条路。写个dfs把遍历的先后顺序换一下,判断有没有重合的地方就好了,特判(1,1)点是否有可能不能行走就好了

#include<bits/stdc++.h>
using namespace std;
const int maxn =  20;
int ans;
int n;
char mp[maxn][maxn];
bool vis[maxn][maxn];
int dx[4] = { 0,1 };
int dy[4] = { 1,0 };
int ex, ey;
struct node {
    int x, y;
}s[maxn], a[maxn];
int k;
int flag = 0;
int cnt1, cnt2;
void dfs(int x, int y) {
    if (x == n && y == n) { cnt1 = k; flag = 1; return; }
    for (int i = 0; i <= 1; i++) {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if (xx > 0 && xx <= n && yy > 0 && yy <= n && vis[xx][yy] == 0 && mp[xx][yy] == '.') {
            s[k].x = xx;
            s[k++].y = yy;
            dfs(xx, yy);
            if (flag == 1) return;
            vis[xx][yy] = 1;
            k--;
        }
    }
}
int flag1 = 0;
void dfs1(int x, int y) {
    if (x == n && y == n) { cnt2 = k; flag1 = 1; return; }
    for (int i = 1; i >= 0; i--) {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if (xx > 0 && xx <= n && yy > 0 && yy <= n && vis[xx][yy] == 0 && mp[xx][yy] == '.') {
            a[k].x = xx;
            a[k++].y = yy;
            dfs1(xx, yy);
            if (flag1 == 1) return;
            vis[xx][yy] = 1;
            k--;
        }
    }
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cin >> mp[i][j];
            }
        }
        ans = 0;
        k = 1; flag = 0;
        memset(vis, 0, sizeof(vis));
        dfs(1, 1);
        k = 1; flag1 = 0;
        memset(vis, 0, sizeof(vis));
        dfs1(1, 1);/*
        for (int i = 1; i <= cnt2 - 2; i++) {
            cout << a[i].x << " " << a[i].y << endl;
        }
        for (int i = 1; i <= cnt1 - 2; i++) {
            cout << s[i].x << " " << s[i].y << endl;
        }*/
        int flagg = 0;
        for (int i = 1; i <= cnt2 - 2; i++) {
            for (int j = 1; j <= cnt1 - 2; j++) {
                if (a[i].x == s[j].x&&a[i].y == s[j].y) {
                    flagg = 1;
                }
            }
        }
        if (mp[1][1] == '#' || mp[n][n] == '#') cout << 0 << endl;
        else if (flag == 0)     cout << 0 << endl;
        else if (flagg == 0) cout << 2 << endl;
        else cout << 1 << endl;

    }
    return 0;
}

3.虫族基地

情况有点多我有点顶不住
给你一幅图,有两个虫长在第1行和第n行的给定位置,然后会每秒以曼哈顿距离扩散一个单位,问几秒的平方后从(1,1)到(n,m)的路径会不存在
就这样 再那样就好了
考虑一下1个虫的单纯的行列扩散,再两个虫的同时的行列扩散,判断几种情况就好了

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100;
typedef long long ll;
int main() {
	ios::sync_with_stdio;
	cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		ll n, m, x1, x2;
		cin >> n >> m >> x1 >> x2;
		if (x1 == 1 || x2 == m) cout << 0 << endl;
		else {
			ll minn = min(x1 - 1, m - x2);
			minn = min(minn, n - 1);
			ll num1 = abs(x1 - x2);
			if (num1 % 2 == 0 && n % 2 == 0) {
				minn = min(minn, num1 / 2 + (n - 2) / 2);
			}
			else if (num1 % 2 == 0 && n % 2 == 1) {
				minn = min(minn, num1 / 2 + (n-2)/ 2);
			}
			else if (num1 % 2 == 1 && n % 2 == 0) {
				minn = min(minn, num1 / 2 + (n-1) / 2);
			}
			else {
				minn = min(minn, num1 / 2 + n / 2 );
			}
			cout << minn*minn << endl;
		}
	}
	return 0;
}

4.环上行走

从1到n里面存在一个顺序相连的环,n的后面连1,一共n-1轮,第 i 轮可以选择向左或向右 i 步,需要n-1的轮的时候没有点是重复的,问有几种方案数。
本来想打个表因为n最大才80,打的时候发现竟然跑的这么快,那就直接交了

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100;
bool vis[maxn];
int n;
int ans;
void dfs(int x,int pos) {
    if (x == n ) { ans++; return; }
    int num1 = (pos + x);
    int num2 = (pos - x);
    if (num1 > n)num1 -= n;
    if (num2 < 1)num2 += n;
    //cout << num1 << " " << num2 << endl;
    if (vis[num1] == 0) {
        vis[num1] = 1;
        dfs(x + 1, num1);
        vis[num1] = 0;
    }
    if (vis[num2] == 0) {
        vis[num2] = 1;
        dfs(x + 1, num2);
        vis[num2] = 0;
    }
    return;
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        ans = 0;
        cin >> n;
        vis[1] = 1;
        dfs(1, 1);
        memset(vis, 0, sizeof(vis));
        cout << ans << endl;
    }

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值