Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3)

A

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <utility>
using namespace std;

typedef long long ll;
const int qq = 1e5 + 10;
ll num[qq];

int main(){
	int n, m, k; cin >> n >> m >> k;
	int x, y;
	int c = m*2;
	y = k%c == 0? k/c:k/c+1;
	char s;
	k = k%c == 0? c : k%c;
	if(k%2 == 0)	x = k/2;
	else x = k/2 + 1;
	if(k%2 == 1)	s = 'L';
	else	s = 'R';
	cout << y << " " << x << " " << s << endl;
	return 0;
}

B

题意:给出两个字符串a,b, 问能否通过字母的映射使得字符串b变成a

思路: 唯一的坑点就在与多重映射, 因为如果是字母a -> 字母a的话这样情况是不算一次映射的.

哈哈 fst的时候只过了700+     和我一起打的伙伴们都挂了  我就一个在哪里出力瑟瑟发抖

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <utility>
using namespace std;

typedef long long ll;
const int qq = 1e5 + 10;
string a, b;
int str[1005];
int o[1005];
struct C{
    char a, b;
}num[1005];

int main(){
	cin >> a >> b;
	int k =  0;
	bool f = true;
	memset(str, 0, sizeof(str));
	memset(o, 0, sizeof(o));
	for(int i = 0; i < (int)b.size(); ++i){
		if(str[b[i]])	continue;
		o[a[i]]++;
		if(o[a[i]] >= 2)	f = false;
		str[b[i]] = a[i];
	}
	if(!f){
		cout << -1 << endl;
		return 0;
	}
	for(int i = 0; i < (int)b.size(); ++i){
		if(!str[b[i]])	continue;
		b[i] = str[b[i]];
	}
	int p = 0;
	if(a == b){
		for(int i = 0; i < 200; ++i)
			if(str[i]){
            	char q, w;
            	q = i, w = str[i];
            	if(q == w)	continue;
            	if(q > w)	swap(q, w);
            	bool flag = true;
            	for(int j = 0; j < p; ++j)
            		if(num[j].a == q && num[j].b == w)	flag = false;
            		else if(num[j].a == q || num[j].b == w)	f = false;
            	if(flag){
             		num[p].a = q, num[p].b = w;
             		p++;
            	}
			}
		if(!f){
			cout << -1 << endl;
			return 0;
		}
        cout << p << endl;
        for(int i = 0; i < p; ++i)
            cout << num[i].a << " " << num[i].b << endl;
	}else	cout << "-1" << endl;
	return 0;
}

C

题意:给出n次操作, 每次可以向上 向下 向左 向右走一个单位, 他每次都是从一个点走到另外一个点 并且走的一定是最短距离, 求一共进行了多少次这样的操作

思路:按照过程模拟即可 每次从始发地到目的地走最短距离, 那么也就是说每次走之后距离始发地越远则还在像目的地移动,  如果距离一旦减少, 说明走之前的点就是目的地, 然后更新事发地, 一直模拟下去即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <utility>
using namespace std;

typedef long long ll;
const int qq = 2e5 + 10;
typedef pair<ll, ll> pill;
map<pill, int> Q;
bool vis[qq];
string s;
ll dis;
ll o1, o2;

bool f(ll a, ll b){
	if(abs(a-o1)*abs(a-o1)+abs(b-o2)*abs(b-o2) > dis){
		dis = abs(a-o1)*abs(a-o1)+abs(b-o2)*abs(b-o2);
		return true;
	}
	return false;
}

int main(){
	ll n; cin >> n;
	ll x, y;
	x = y = 0;
	o1 = o2 = 0;
	dis = 0;
	cin >> s;
	int k = 0;
	for(int i = 0; i < n; ++i){
        int xx = x, yy = y;
		if(s[i] == 'U')	x = x + 1;
		else if(s[i] == 'D')	x = x - 1;
		else if(s[i] == 'R')	y = y + 1;
		else if(s[i] == 'L')	y = y - 1;
		if(!f(x, y)){
            dis = 1; Q[make_pair(xx, yy)] = 1;
            k++;
            o1 = xx; o2 = yy;
		}
	}
	k++;
	cout << k << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值