第20届上海大学程序设计联赛春季赛(补题)

赛时出5题,罚时290min,补题顺序为题目难度顺序。

不知道为啥现在才补题,,每天不知道在忙啥,乐

D - 并不智能的卡牌AI(签到,整除)

思路:做除法,向上取整,注意特判0的情况。

AC Code:

#include <bits/stdc++.h>
#pragma GCC optimize(2)

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 35;
int n, m;

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cin >> m >> n;
	if (m && !n) {
		std::cout << -1 << '\n';
		return 0;
	}
	if (!m && !n) {
		std::cout << 0 << '\n';
		return 0;
	}
	std::cout << (int)ceil((double)m / (double)n) << '\n';
	return 0;
}

C - 古老的恩尼格玛机(签到,map)

思路:字母两两对应,map一通乱搞。

AC Code:

#include <bits/stdc++.h>
#pragma GCC optimize(2)

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e6 + 5;
char c, s;
int n;
std::string ss[N];

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::map<char, char>mp;
	for (int i = 1; i <= 13; i++) {
		std::cin >> c >> s;
		mp[c] = s;
		mp[s] = c;
	}
	std::cin >> n;
	for (int i = 0; i < n; i++) {
		std::cin >> ss[i];
		for (int j = 0; j < ss[i].length(); j++) {
			ss[i][j] = mp[ss[i][j]];
		}
	}
	for (int i = 0; i < n; i++) {
		std::cout << ss[i] << " \n"[i == n - 1];
	}
	return 0;
}

 H - 差不多得了(签到,思维)

 思路:在同一位置相连的1对答案的贡献是一样的,因为要找不同的子序列,那就找到不同的连续的1,这就是子序列的方案且满足子序列的和是原数组-1,因为这个题中不存在a[i]=0的情况,不需要额外考虑。

AC Code:

#include <bits/stdc++.h>
#pragma GCC optimize(2)

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 35;
int t, n;
ll a[N];

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cin >> t;
	while (t--) {
		std::cin >> n;
		int cnt = 0;
		std::vector<int>vec;
		for (int i = 1; i <= n; i++) {
			std::cin >> a[i];
		}
		vec.push_back(a[1]);
		for (int i = 2; i <= n; i++) {
			if (a[i] == a[i - 1] && a[i] == 1)
				continue;
			vec.push_back(a[i]);
		}
		for (int i = 0; i < vec.size(); i++) {
			if (vec[i] == 1)
				cnt++;
		}
		std::cout << cnt << '\n';
	}
	return 0;
}

os:之前cf有一个类似的题,但是是存在元素等于0,要额外考虑0的个数。

A - 如何才能穿过传送门(模拟)

思路:数据范围较小,直接模拟,具体实现是用while循环,不满足条件break即可。

AC Code:

#include <bits/stdc++.h>
#pragma GCC optimize(2)

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e3 + 5;
int n, m, q, x, y;
int a[N];
bool vis[N];

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cin >> n >> m >> q;
	std::map<int, int>mp;
	for(int i=0;i<=n;i++){
	    mp[i]=0;
    }
	for (int i = 1; i <= m; i++) {
		std::cin >> x >> y;
		mp[x] = y;
	}
	for (int i = 1; i <= q; i++) {
		std::cin >> a[i];
		vis[a[i]] = true;
	}
	bool flag = true;
	int pos = 0;
	while (pos < n) {
		pos++;
		if (vis[pos]) {
			flag = false;
			break;
		}
		if (mp[pos])
			pos = mp[pos];
	}
	std::cout << (flag ? "YES" : "NO") << '\n';
	return 0;
}

 G - 多吃蘑菇

思路:在树上的到每一个点的路径仅有唯一一条,直接DFS,记录到每一个点可以吃到的蘑菇的最大重量,具体实现可以使用数组模拟某种颜色最大值的情况。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N=1e5+5;
ll n;
ll w[N],c[N],ans[N],max[N];
std::vector<ll>vec[N];

void dfs(ll u){
    if(vec[u].empty()){
        return;
    }
    for(auto i:vec[u]){
        ans[i]=ans[u]-max[c[i]]+std::max(w[i],max[c[i]]);
        ll t=max[c[i]];
        max[c[i]]=std::max(w[i],max[c[i]]);
        dfs(i);
        max[c[i]]=t;
    }
}

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin>>n;
    for(int i=1;i<=n;i++){
        std::cin>>w[i];
    }
    for(int i=1;i<=n;i++){
        std::cin>>c[i];
        max[c[i]]=0;
    }
    for(int i=1;i<n;i++){
        int u,v;
        std::cin>>u>>v;
        vec[u].push_back(v);
    }
    ans[1]=w[1];
    max[c[1]]=w[1];
    dfs(1);
    for(ll i=1;i<=n;i++){
        std::cout<<ans[i]<<" \n";
    }
    return 0;
}

 os:DFS注意回溯,有个同学因为回溯了修改之后的答案WA了好多发hhh。

I - 数学题真难啊

 思路:看上去是完全背包求方案数,但是要解决这个题需要一些处理。我们可以把背包的剩余量改为模3的余数和模9的余数,最后求的模两数等于0的方案数相乘即可,那么对于每个数,我们预处理放到数组中的就是0~9模3余0,1,2的数字数量,模9余0,1,2,3,4,5,6,7,8的数量。奇偶分开处理,具体细节见代码,注意开ll。

AC Code:

#include <bits/stdc++.h>
#pragma GCC optimize(2)

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 998244353;
const int N = 3e5 + 5;
const int INF = 0x3f3f3f3f;
int n, x;
int a[N], b[N];
int mod3[] = {4, 3, 3};

int mod9[] = {2, 1, 1, 1, 1, 1, 1, 1, 1};
ll f1[N][3], f2[N][10];


int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cin >> n;
	int a, b;
	if (n % 2) {
		a = n / 2, b = n - a;
	} else
		a = b = n / 2;
	for (int i = 0; i < 3; i++)
		f1[1][i] = mod3[i];
	for (int i = 0; i < 9; i++)
		f2[1][i] = mod9[i];
	for (int i = 1; i <= b; i++) {
		for (int j = 0; j < 3; j++) {
			for (int k = 0; k < 3; k++) {
				f1[i][j] += f1[i - 1][(j - k + 3) % 3] * mod3[k] % mod;
				f1[i][j] %= mod;
			}
		}
	}
	for (int i = 1; i <= a; i++) {
		for (int j = 0; j < 9; j++) {
			for (int k = 0; k < 9; k++) {
				f2[i][j] += f2[i - 1][(j - k + 9) % 9] * mod9[k] % mod;
				f2[i][j] %= mod;
			}
		}
	}
	if (n == 1)
		std::cout << 4 << '\n';
	else
		std::cout << (f1[b][0] * f2[a][0]) % mod << '\n';
	return 0;
}

os:是学习的同学的,,他之前做过类似的题,,tqltql

B - 逃离魔爪

 思路:啊树状数组啊,那没事了,等我学会了回来补QWQ

若有错误请指教,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值