Codeforces Beta Round #73(Div2)

这套CF练习题感觉有点迷,坑好多

传送门

A - Chord

思路:
  • 给予C 、C#、D、D#、E、F、F#、G、G#、A、B、H,这12个符号,题目给予3个符号,如果相隔 4 3,那么就输出“major”,如果相隔3 4,就输出“minor”,否则就输出“strange”。
  • 排着循环遍历即可,判断他们之间的距离(mp存一下),然后判断输出即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <stack>
#include <cmath>
#include <deque>

using namespace std;

typedef long long ll;

const int N = 100010, M = 200010;
const int mod = 1e9 + 7;

struct node
{
	string st;
	int n;
}ans[N];

bool cmp(node x, node y){
	if (x.st[0] == y.st[0]) return x.n < y.n;
	return x.st[0] < y.st[0];
}

// string s[12] = {"C","C#","D","D#","E","F","F#","G","G#","A","B","H"};

unordered_map<string ,int> mp;



int main(){
    string a, b, c;
    cin>>a>>b>>c;
    mp["C"] = 1;
	mp["C#"] = 2;
	mp["D"] = 3;
	mp["D#"] = 4;
	mp["E"] = 5;
	mp["F"] = 6;
	mp["F#"] = 7;
	mp["G"] = 8;
	mp["G#"] = 9;
	mp["A"] = 10;
	mp["B"] = 11;
	mp["H"] = 12;
    ans[0].st = a;
    ans[0].n = a.length();
    ans[1].st =  b;
    ans[1].n = b.length();
    ans[2].st = c;
    ans[2].n = c.length();
    sort(ans, ans + 3, cmp);
    int f = 0;
    for (int i = 0; i < 3; i ++){
    	int x = mp[ans[i%3].st];
    	int y = mp[ans[(i + 1)%3].st];
    	int z = mp[ans[(i + 2)%3].st];
    	int xy = (12 + y - x ) % 12;
    	int yz = (12 + z - y ) % 12;
    	if (xy == 4 && yz == 3) {
    		puts("major");
    		f = 1;
    		return 0;
    	}
    	if (xy == 3 && yz == 4){
    		puts("minor");
    		f = 1;
    		return 0;
    	}
    }
    if (!f) puts("strange");
    return 0;
}


B - Keyboard

思路:
  • 这题比较坑,首先说一下坑点,就是S算Shift(就是必须S + s 才能敲出来S),还有就是字符不一定就出现一次(我一开始以为就1个)
  • 大体思路就是先存储一遍S的位置,然后我们再遍历求小写字母能敲出大写字母时距离最近的S的距离,然后遍历即可
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <stack>
#include <cmath>
#include <deque>
#include <set>

using namespace std;

typedef long long ll;

const int N = 100010, M = 200010;
const int mod = 1e9 + 7;

char a[1010][1010];

ll g[N];

struct node
{
	int x, y;
}mp[N],bb[N];


int main(){
	int cnt = 0;
	set<char> res;
    int n, m, x;
    scanf("%d%d%d",&n,&m,&x);
    int xx = 0;
    for (int i = 1; i <= n; i++){
    	string st; 
    	cin>>st;
    	for (int j = 0; j < m; j ++){
    		a[i][j + 1] = st[j]; 
    		if (a[i][j + 1] == 'S'){
    			xx = i;
    			bb[cnt].x = i;
    			bb[cnt ++].y = j + 1;
    		}
    		// mp[(int)a[i][j + 1]].x = i;
    		// mp[(int)a[i][j + 1]].y = j + 1;
    		res.insert(a[i][j + 1]);
    	}
    	
    }
    for (int i = 0; i < 10000; i ++){
    	g[i] = 1000000000000;
    }
    for (int i = 1; i <= n; i++){
    	for (int j = 1; j <= m; j++){
    		char s = a[i][j];
    		if (s == 'S') continue;
    		g[(int)s] = 0;

    		if (s >= 'a' && s <= 'z' && xx != 0){
				for (int k = 0; k < cnt; k ++){
					ll dist = ((i - bb[k].x) * (i - bb[k].x) + (j - bb[k].y) * (j - bb[k].y));
					g[int(s) - 32] = min(g[int(s) - 32],dist);
				}
    		}
    	}
    }
    int q;
    scanf("%d",&q);
    int num = 0;
    string st;
    cin>>st;
    for (int i = 0; i < q; i++){
    	char s = st[i];
    	// printf("%f\n",g[(int)s]);
    	if (g[(int)s] == 1000000000000) {
    		puts("-1");
    		return 0;
    	}
    	else{
    		if (g[(int)s] > x * x) num ++;
    	}
    }
    printf("%d\n",num);
    return 0;
}


C - Trains

思路:
  • 稍微有点绕,最终求去哪个女友那里次数多
  • 首先我们先求出他们的最小公倍数,这样我们按照一个周期来计算,直接暴力即可,我们一个一个判断该时间段,应该去哪个女友那里,看例子应该能看明白,比如 2 3, 那么1 2 时刻肯定是等车去女友D那里,3时刻去女友M,4时刻去女友D,这里最终的关键是最后,5 6 时刻,他们都相同,相同时刻都可以去女友那里,然后去去的少的女友那里,所以5 6 去女友M那里,所以他们的时间相同,所以是Equal。
  • 所以我们只要慢慢取最小值即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <stack>
#include <cmath>
#include <deque>

using namespace std;

typedef long long ll;

const int N = 100010, M = 200010;
const int mod = 1e9 + 7;

long long gcd(long long a,long long b){
    if (a > b){
        long long temp = a;
        a = b;
        b = temp;
    }
    while(b%a!=0){
        long long temp = b%a;
        b = a;
        a = temp;
    }
    return a;
}

int main(){
    ll a, b;
    scanf("%lld%lld",&a,&b);
    ll g = a * b / gcd(a,b);
    ll n1 = 1, n2 = 1;
    ll mi = 0;
    ll ra = 0, rb = 0;
    while(1){
    	ll x = n1 * a;
    	ll y = n2 * b;
    	ll t = min(x, y);
    	if (t == x) n1 ++;
    	else n2 ++;
    	if (t == g){
    		if (ra > rb) rb += g - mi;
    		else ra += g - mi;
    		break;
    	}
    	if (t % a == 0) ra += t - mi;
    	if (t % b == 0) rb += t - mi;
    	mi = t;
    }
    if (ra == rb) puts("Equal");
    else if (ra > rb) puts("Dasha");
    else puts("Masha");
    return 0;
}


D - Vasya and Types

思路:
  • 首先存储一下初始void(用mp存一下),然后每次操作:
  • 如果是def ,那么我们计算& 和 * 的数目,然后计算原本的字符,然后如果num <= 0 ,那么直接err, 而且err后无论有多少 * ,都是err(很坑),然后我们排着模拟计算即可,然后最后计算数值进行保存。
  • 如果是of ,那么直接输出即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
#include <stack>
#include <cmath>
#include <deque>

using namespace std;

typedef long long ll;

const int N = 100010, M = 200010;
const int mod = 1e9 + 7;

string a, b, c;
int num = 0;

unordered_map<string,int> mp;

void solve(){
	cin>>b;
	int n = b.length();
	string d = "";
	num = 0;
	int cnt = 0;
	for (int i = 0; i < n; i++){
		if (b[i] == '&'){
			cnt --;
		}
		else if (b[i] == '*'){
			cnt ++;
		}
		else{
			d += b[i];
		}
	}
	num = mp[d];
	if (mp[d] > 0) num += cnt;
	else num = 0;

}

int main(){
    int n;
    scanf("%d",&n);
    mp["void"] = 1;
    for (int i = 1; i <= n; i++){
    	cin>>a;
    	if (a == "typedef"){
    		solve();
    		cin>>c;
    		mp[c] = num;
    	}
    	else{
    		solve();
    		if (num <= 0) puts("errtype");
    		else{
    			printf("void");
    			for (int i = 0; i < num - 1; i ++){
    				printf("*");
    			}
    			puts("");
    		}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值