Codeforces Round #750 (Div. 2)

总的来说挺失败的,签到题卡的比后面的题还要久,雀氏菜

A. Luntik and Concerts

传送门
A最简单但卡的最久,果然是思维题硬伤,写了一大堆还抵不过栋哥哥三四行代码,多吃点核桃补补呜呜呜
题意:给你三首分别为一分钟,两分钟,三分钟的歌,歌曲数量为a,b,c,把所有的歌安排到两场比赛中,使得两场比赛各自的总时间差值最小
题解:我们简单模拟可以知道插值要么是0,要么是1,我们可以把三首歌各自的数量q取余2,结果就是(a+2b+3c)%2,原因是,若1分钟和2分钟取余后剩1(2分钟和3分钟剩1同理),当三分钟取余后是0,那么就让1分钟和2分钟的歌分到两场比赛,差值就是1;若1分钟和3分钟剩1,当2分钟取余后为0,那么说明2分钟的歌至少有2个,我们让1分钟和3分钟在一场比赛,跟两个2分钟抵消就可;当a,b,c都剩余1,那么就让1分钟和2分钟凑一起,抵消3分钟
code:

# include <iostream>
# include <algorithm>
# include <string.h>
# include <cstring>
 
using namespace std;
 
int main(){
	int n;
	cin >> n;
	while (n --){
		int a, b, c;
		cin >> a >> b >> c;
		a%=2,b%=2,c%=2;
		b*=2,c*=3;
		cout << (a+b+c)%2 << endl;
	}	
	return 0;
}

B. Luntik and Subsequences

传送门
题意:求有多少种子序列,可以通过删除序列某些数(或不删除),使得子序列的和等于这个序列总和sum 减去一
题解:我们统计序列1的个数num1,这样可以删除num1次,在统计0的个数num0,0可以删除:由(0)变成(),因此答案就是num1*pow(2,num0)
code:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <cmath>
 
using namespace std;
 
typedef long long ll;
 
const int N = 1e5 + 10;
 
int ans[2010];
int st[2021];
int a[100];
 
ll fast (ll b){
	ll ans = 1;
	ll a = 2, p = 1e9 + 10;
	while (b){
		if (b % 2) ans *= a ;
		b /= 2;
		a = a * a ;
	}
	return ans;
}
 
int main(){
	int t;
	cin >> t;	
	while (t --){
		ll n,k;
		ll num1 = 0, num0 = 0;
		cin >> n;
		for (ll i = 1; i <= n; i ++){
			cin >> k;
			if (k == 1)
				num1 ++;
			else if (k == 0)
				num0 ++; 
		}
		cout << num1 * fast(num0) << endl;
	}
	return 0;
}

C. Grandma Capa Knits a Scarf

传送门
题意:让你删除某一个字符,可重复删除,但不能删除别的字符,(或者不删除),使得它是回文字符,求解删除字符个数最少的情况是几个
题解:由于字符实在a~z之间,我们直接枚举就好了,从a开始枚举,运用双指针,指向最左和最右两点,如果这两点数值相同,就继续向中间遍历,如果左边或者右边的字符等于外层遍历的字符,说明可以删除它,ans++,再继续移动指针,如果左右两边不相等且不等于外层遍历的字符,直接跳出就可,不存在回文字符

#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <cmath>
 
using namespace std;
 
typedef long long ll;
 
const int N = 2e5 + 10;
 
char a[N];
 
ll fast (ll b){
	ll ans = 1;
	ll a = 2, p = 1e9 + 10;
	while (b){
		if (b % 2) ans *= a ;
		b /= 2;
		a = a * a ;
	}
	return ans;
}
 
int main(){
	int t;
	cin >> t;	
	while (t --){
		int n;
		cin >> n;
		string s;
		cin >> s;
		int res = N;
		for (char ch = 'a'; ch <= 'z'; ch ++){
			int l = 0, r = n - 1;
			int ans = 0;
			while (l < r){
				if (s[l] == s[r]) l ++, r --;
				
				else if (s[l] == ch) l ++, ans ++;
				
				else if (s[r] == ch) r --, ans ++;
				
				else{
					ans = n + 100;
					break;
				}
			}
			res = min (res , ans);	
		}
		if (res == n + 100) res = -1;
		cout << res << endl;
	}
	return 0;
}

D. Vupsen, Pupsen and 0

传送门
这题张师姐巴拉巴拉讲一堆也没听懂,自己看了看,就是个简单的奇偶性问题,不过坑还是很多的
题意:给你一个不含有0的数组a[i],让你写出另一个等长的不含有0的数组b[i],使得这两个数组乘积和a[1]*b[1] + ... 等于 0
题解:数组个数是偶数,数组b就让它跟a数组两两抵消,如{a,b}和{-b,a},数组个数为奇数,前n-3项按照偶数处理,剩下三个,也可以推测抵消方式(我觉得这是这题最恶心的地方),而且要注意不能为0
code:

#include <iostream>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <math.h>
 
using namespace std;
 
const int N = 1e5 + 10;
 
int a[N];
 
int main(){
    int t;
    cin >> t;
    while (t --){
        int n;
        cin >> n;
        for (int i = 1; i <= n; i ++)
            cin >> a[i];
       if(!(n & 1)){
        for (int i = 1; i <= n; i += 2)
            cout << -1 * a[i + 1] << ' ' << a[i] << ' ';
        cout << endl;
        }
        else{
            for (int i = 1; i <= n - 3; i += 2)
                cout << -1 * a[i + 1] << ' ' << a[i] << ' ';
            
            int x = a[n - 2];
            int y = a[n - 1];
            int z = a[n];
    
            if(x + z != 0)
                printf("%d %d %d\n", y, -(x + z), y);
            
            else if(x + y != 0)
                printf("%d %d %d\n", z, z, -(x + y));
            
            else
                printf("%d %d %d\n", -(z + y), x, x);
            
        }
    }
    return 0;
    //  2 1 1 ->   1 1 -3  
    // 1 -1 2 ->  -1 -3 -1 
 }
posted @ 2021-10-26 19:04  Gsding  阅读(24)  评论(0)    收藏  举报