codeforces 1118 A(简单模拟) B (思维) C(构造)

A. Water Buying(简单模拟)

题目链接: codeforces 1118A

题意:  

     想要正好 n 升汤,有个容量为1的勺子,每次使用花费 为a, 容量为2的勺子,每次使用花费为 b,问最小花费

题解:

   判断使用两次1升的勺子的花费是否大于使用一次2升的 勺子

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	int t;
	cin >> t;
	while(t--){
		ll n, ans, a, b;
		cin >> n >> a >> b;
		if(a * 2 <= b){
			ans = n * a; // 用一升的勺子
		}
		else{
			ans = n / 2 * b + n % 2 * a; // 先用两升的勺子,最后一升用一升的勺子
		}
		cout << ans << endl;
	}
	return 0;
} 

B. Tanya and Candies(思维)

题目链接:codeforces 1118B

题意:

    给一个大小为n的数组,将其中一个元素拿出去后的新数组中,奇数位置的和等于偶数位置的和的方案数,

举例 :

   1    4    3    3

① 将第一个拿出,新数组为 [ 4 , 3  ,  3],奇数位置的和为 4 + 3 = 7;  偶数位置的和为  3

② 将第二个拿出 ,新数组为[ 1,   3,   3] ,奇数位置的和为1 + 3 = 3;偶数位置的和为 3

③ 将第三个拿出, 新数组为[ 1,  4,  3] , 奇数位置的和为 1 + 3 = 4; 偶数位置的和为 4 ,  ans ++

④ 同三  ans ++;

答案为 2

题解:

     分别求出 奇数位置和偶数位置的前缀和,然后从哪个位置分开后,奇数和偶数交换(代码理解)

比如拿出的初始位置为 3, 那么奇数位置的和就是 3 前面的奇数位置的和 + 3后面偶数位置的和,同理偶数位置也一样

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
int a[maxn], odd[maxn], even[maxn];
int main(){
	int n;
	cin >> n;
	odd[0] = even[0] = 0;
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		if(i % 2 == 1){
			odd[i] = odd[i-1] + a[i];
			even[i] = even[i-1];
		}
		else{
			even[i] = even[i-1] + a[i];
			odd[i] = odd[i-1];
		}
	}
	int ans1 = 0, ans2 = 0, ans = 0;
	for(int i = 1; i <= n; i++){
		if(i % 2 == 1){
			ans1 = odd[i-1] + even[n] - even[i-1];
			ans2 = even[i-1] + odd[n] - odd[i];
		}
		else{
			ans1 = odd[i-1] + even[n] - even[i];
			ans2 = even[i-1] + odd[n] - odd[i-1];
		}
		if(ans1 == ans2){
			ans++;
		}
	}
	cout << ans << endl;
	return 0;
}

C. Palindromic Matrix(构造)

题目链接:codeforces 1118C

题意:  

   给出n^2 个数,问能否构成一个矩阵,使矩阵 行和列 翻转过来仍然一样,如果可以,输出YES和那个矩阵,否则输出 NO

题解:

   模拟(小心模拟),我是先排列四个角,如果是奇数,再将多的数排在中间的行和列

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
int a[maxn], b[maxn], mp[501][501];
vector<int> v;
int main(){
	int n, ans = 0, y = 0;
	cin >> n;
	memset(b, 0, sizeof(b));
	
	for(int i = 1; i <= n*n; i++){
		cin >> a[i];
		b[a[i]]++;
	}
	sort(a+1, a+1+n);
	int even = 0, odd = 0, u = 0, res = 0;
	for(int i = 1; i <= 1000; i++){
		res += b[i]/4;
		if(b[i] % 4 != 0){
			even++;
		}
		if(b[i] % 4 == 1 || b[i] % 4 == 3){
			ans = i;
			odd++;
		}
		else if(n % 2 == 0 && b[i] % 4 == 2){
			u++;
		}
	}
	if(n == 1){
		cout << "YES" << endl << a[1] << endl;
		return 0;
	}
    // 判断能否构成矩阵的条件
	else if((n % 2 == 1 && (odd > 1 || u >= n)) || (n % 2 == 0 && even > 0) || res < (n/2)*(n/2)){
		cout << "NO" << endl;
		return 0;
	}
	else{
		cout << "YES" << endl;
		int j = 1, i = 1, k = 1;
		while(i <= n/2){
			while(b[k] <= 3){
				k++;
			}
			if(b[k] >= 4){
				mp[i][j] = mp[i][n-j+1] = mp[n-i+1][j] = mp[n-i+1][n-j+1] = k;
				b[k] -= 4;
				
			}
			if(j > n/2){
				j = 1;i++;
			}
			else{
				j++;
			}
			if(j > n/2){
				j = 1; i++;
			}
		}
		if(n % 2 != 0){
			i = 1;k = 1;
			j = 1;
			while(k <= 1000){
				while(b[k] < 2){
					k++;
				}
				if(i <= n / 2){
					mp[i][n/2+1] = mp[n-i+1][n/2+1] = k;
					b[k] -= 2;
					i++;
				}
				else if(j <= n/2){
					mp[n/2+1][j] = mp[n/2+1][n-j+1] = k;
					b[k] -= 2;
					j++;
				}
			}
			mp[n/2+1][n/2+1] = ans;
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++){
			cout << mp[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}
// 在第8个样例卡了,样例如下

/*
19
1 1 1 1 1 2 2 2 2 5 2 2 2 2 1 1 1 1 1 
2 2 3 3 3 3 3 4 4 9 4 4 3 3 3 3 3 2 2 
4 4 4 4 4 4 4 4 5 17 5 4 4 4 4 4 4 4 4 
6 6 6 6 7 7 7 7 8 19 8 7 7 7 7 6 6 6 6 
8 8 8 8 8 9 9 9 10 20 10 9 9 9 8 8 8 8 8 
10 10 10 10 11 11 12 12 12 20 12 12 12 11 11 10 10 10 10 
13 13 13 14 14 14 14 15 15 20 15 15 14 14 14 14 13 13 13 
15 16 16 16 16 16 17 17 17 20 17 17 17 16 16 16 16 16 15 
17 17 18 18 18 18 18 19 19 20 19 19 18 18 18 18 18 17 17 
2 6 14 19 19 20 20 20 20 14 20 20 20 20 19 19 14 6 2 
1 1 1 1 1 2 2 2 2 5 2 2 2 2 1 1 1 1 1 
2 2 3 3 3 3 3 4 4 9 4 4 3 3 3 3 3 2 2 
4 4 4 4 4 4 4 4 5 17 5 4 4 4 4 4 4 4 4 
6 6 6 6 7 7 7 7 8 19 8 7 7 7 7 6 6 6 6 
8 8 8 8 8 9 9 9 10 20 10 9 9 9 8 8 8 8 8 
10 10 10 10 11 11 12 12 12 20 12 12 12 11 11 10 10 10 10 
13 13 13 14 14 14 14 15 15 20 15 15 14 14 14 14 13 13 13 
15 16 16 16 16 16 17 17 17 20 17 17 17 16 16 16 16 16 15 
17 17 18 18 18 18 18 19 19 20 19 19 18 18 18 18 18 17 17 
*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值