Codeforces Round #529 (Div. 3) C. Powers Of Two题解及思路

26 篇文章 0 订阅
7 篇文章 0 订阅

 

       time limit per test 1 second memory limit per test 256 megabytes input

standard input output standard output Ivan wants to play a game with you. He picked some string ss of length nn consisting only of lowercase Latin letters.

 

        You don't know this string. Ivan has informed you about all its improper prefixes and suffixes (i.e. prefixes and suffixes of lengths from 11 to n−1n−1), but he didn't tell you which strings are prefixes and which are suffixes.

 

        Ivan wants you to guess which of the given 2n−22n−2 strings are prefixes of the given string and which are suffixes. It may be impossible to guess the string Ivan picked (since multiple strings may give the same set of suffixes and prefixes), but Ivan will accept your answer if there is at least one string that is consistent with it. Let the game begin!

Input

The first line of the input contains one integer number nn (2≤n≤1002≤n≤100) — the length of the guessed string ss.

The next 2n−22n−2 lines are contain prefixes and suffixes, one per line. Each of them is the string of length from 11 to n−1n−1 consisting only of lowercase Latin letters. They can be given in arbitrary order.

It is guaranteed that there are exactly 22 strings of each length from 11 to n−1n−1. It is also guaranteed that these strings are prefixes and suffixes of some existing string of length nn.

Output

Print one string of length 2n−22n−2 — the string consisting only of characters 'P' and 'S'. The number of characters 'P' should be equal to the number of characters 'S'. The ii-th character of this string should be 'P' if the ii-th of the input strings is the prefix and 'S' otherwise.

If there are several possible answers, you can print any.

 

来自 <https://codeforces.com/contest/1092/problem/C>

 

题意大概是给出两个数n和k,要求你将n分解为k个2的指数相加。

先给出我一开始的错误思路,这个思路是非常清晰且可行的,首先将n化为2进制数(记作num),很快可以发现,k 的取值范围在num中1的个数到n / 2之间——即YES或NO的判断条件,接下来的难题在于如何分解。我是利用贪婪,先找出num中1的位置,再分解

#include<algorithm>
#include <iostream>
#include  <sstream>
#include  <cstring>
#include  <cstdlib>
#include   <string>
#include   <vector>
#include   <cstdio>
#include   <math.h>
#include    <queue>
#include    <stack>
#include      <set>
typedef unsigned long long int ull;
#define rep(i,a,n) for (ull i = a; i < n; ++i)
#define per(i,a,n) for (ull i = n-1; i >= a; --i)
#define SZ(x) ((ull)x.size())
using namespace std;
//head
unsigned long long int update(ull n);
void tanlan(ull n, ull k);
ull ans[10000] = { 0 };
int main()
{
	ull n, k;
	ull num;
	ull flag = 0;
	ull div = 0, sum = 0, qqq = 1;
	cin >> n >> k;
	num = update(n);
	ull numi = num;
	do
	{
		if(numi % 10 == 1)
			div++;
		numi /= 10;
	}while (numi / 10 > 0);
	if ((n == (1 << div)) && k == 1) { cout << "YES" << endl; cout << n << endl;  return 0; }
	div++;
	numi = num;
	sum = n / 2;
	//cout << num << endl;
	//cout << div << "       " << sum << endl;
	if (k >= div && k <= sum)
	{
		cout << "YES" << endl;
		tanlan(num, k);
	}
	else
		cout << "NO" << endl;
	system("pause");
	return 0;
}
unsigned long long int update(ull n)
{
	unsigned long long int  result = 0, k = 1, i, temp;
	temp = n;
	while(temp){
		i = temp % 2;
		result = k * i + result;
		k = k * 10;
		temp = temp >> 1;
	}
	return result;
}
void tanlan(ull num, ull k)
{
	ull N = 0;
	ull div = 0;
	do
	{
		ull qqq = num % 10;
		if (qqq)
		{
			ans[N++] =( 1 << div);
		}
		num /= 10;
		div++;
	} while (num / 10 > 0);
	ans[N++] = 1 << div;
	div = 0;
	while (N < k)
	{
		while (ans[div] <= 2) div++;
		ans[div] = ans[div] >> 1;
		ans[N++] = ans[div];
	}
	sort(ans, ans + N);
	rep(i, 0, N) cout << ans[i] << " ";
	cout << endl;
}

但是这个思路不能AC的问题在于num,99999也就是10E5时num的值就达到了11000011010011111。而题目范围为10E9。所以必须想一个不需要num,直接通过n进行位操作的方法。

然后在探索新方法的道路上遇到了九九八十一难:

 

其中的坑大致上有一开始以为范围上限为n / 2,后来发现上限为n,并把分解的数不能为2改为不能为1,还有数组越界问题,不能开小也不能开大,AC的时候就像女神突然某天接受你的表白了一样!

贴上我的专属AC代码哈哈哈哈

#include<algorithm>
#include <iostream>
#include  <sstream>
#include  <cstring>
#include  <cstdlib>
#include   <string>
#include   <vector>
#include   <cstdio>
#include   <math.h>
#include    <queue>
#include    <stack>
#include      <set>
typedef long long ll;
#define rep(i,a,n) for (int i = a; i < n; ++i)
#define per(i,a,n) for (int i = n-1; i >= a; --i)
#define SZ(x) ((int)x.size())
using namespace std;
//head

#define maxn 1000009
ll a[maxn] = { 0 };
ll map(ll);
ll a_num = 0;
void tanlan(ll, ll, ll);
int main()
{
	ll n, k;
	cin >> n >> k;
	if (k == 1)
	{
		int qqq = 0;
		int N = n;
		while (N)
		{
			N = N >> 1;
			qqq++;
		}
		qqq--;
		if ((1 << qqq) == n) { cout << "YES" << endl; cout << n << endl; return 0; }
	}
	//if (k == n) { cout << "YES" << endl; while (k--) cout << "1 "; cout << endl; return 0; }
	if (k < map(n) || k > n) cout << "NO" << endl;
	else
	{
		cout << "YES" << endl;
		tanlan(n, k, map(n));
	}
	//system("pause");
	return 0;
}
ll map(ll n)
{
	ll vig = 0;
	ll num = 1;
	while (n)
	{
		if (n & 1 == 1) vig++;
		n = n >> 1;
	}
	return vig;
}
void tanlan(ll n, ll k, ll num)
{
	ll div = k - num;
	ll b = 0;
	while (n)
	{
		if (n & 1) a[a_num++] = 1 << b;
		b++;
		n = n >> 1;
		//cout << n << endl;
	}
	ll tag = 0;
	//cout << div << endl;
	while (div--)
	{
		ll c = a_num - 1;
		while (a[tag] == 1) tag++;
		a[tag] = a[tag] >> 1;
		a[a_num++] = a[tag];
	}
	sort(a, a + a_num);
	rep(i, 0, a_num)
		cout << a[i] << " ";
	cout << endl;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值