【GoogleCodeJam2016D】【构造 找规律】Fractiles LG字符串K字符C次变为S个检测位置找金子

Problem D. Fractiles

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read the Quick-Start Guide to get started.
Small input
10 points
Solve D-small
Large input
25 points
Solve D-large

Problem

Long ago, the Fractal civilization created artwork consisting of linear rows of tiles. They had two types of tile that they could use: gold (G) and lead (L).

Each piece of Fractal artwork is based on two parameters: an original sequence of Ktiles, and a complexity C. For a given original sequence, the artwork with complexity 1 is just that original sequence, and the artwork with complexity X+1 consists of the artwork with complexity X, transformed as follows:

  • replace each L tile in the complexity X artwork with another copy of the original sequence
  • replace each G tile in the complexity X artwork with K G tiles

For example, for an original sequence of LGL, the pieces of artwork with complexity 1 through 3 are:

  • C = 1: LGL (which is just the original sequence)
  • C = 2: LGLGGGLGL
  • C = 3: LGLGGGLGLGGGGGGGGGLGLGGGLGL

Here's an illustration of how the artwork with complexity 2 is generated from the artwork with complexity 1:

You have just discovered a piece of Fractal artwork, but the tiles are too dirty for you to tell what they are made of. Because you are an expert archaeologist familiar with the local Fractal culture, you know the values of K and C for the artwork, but you do not know the original sequence. Since gold is exciting, you would like to know whether there is at least one G tile in the artwork. Your budget allows you to hire S graduate students, each of whom can clean one tile of your choice (out of the KC tiles in the artwork) to see whether the tile is G or L.

Is it possible for you to choose a set of no more than S specific tiles to clean, such thatno matter what the original pattern was, you will be able to know for sure whether at least one G tile is present in the artwork? If so, which tiles should you clean?

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each consists of one line with three integers: K, C, and S.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is either IMPOSSIBLE if no set of tiles will answer your question, or a list of between 1 and S positive integers, which are the positions of the tiles that will answer your question. The tile positions are numbered from 1 for the leftmost tile to KC for the rightmost tile. Your chosen positions may be in any order, but they must all be different.

If there are multiple valid sets of tiles, you may output any of them. Remember that once you submit a Small and it is accepted, you will not be able to download and submit another Small input. See the FAQ for a more thorough explanation. This reminder won't appear in problems in later rounds.

Limits

1 ≤ T ≤ 100.
1 ≤ K ≤ 100.
1 ≤ C ≤ 100.
KC ≤ 1018.

Small dataset

S = K.

Large dataset

1 ≤ S  K.

Sample


Input 
 

Output 
 
5
2 3 2
1 1 1
2 1 1
2 1 2
3 2 3

Case #1: 2
Case #2: 1
Case #3: IMPOSSIBLE
Case #4: 1 2
Case #5: 2 6

Note: for some of these sample cases, other valid solutions exist.

In sample case #1, there are four possible original sequences: GG, GL, LG, and LL. They would produce the following artwork, respectively:

  • Original sequence GG: GGGGGGGG
  • Original sequence GL: GGGGGGGL
  • Original sequence LG: LGGGGGGG
  • Original sequence LL: LLLLLLLL

One valid solution is to just look at tile #2. If tile #2 turns out to be G, then you will know for sure the artwork contains at least one G. (You will not know whether the original sequence is GG, GL, or LG, but that doesn't matter.) If tile #2 turns out to be L, then you will know that the original sequence must be LL, so there are no Gs in the artwork. So 2 is a valid solution.

On the other hand, it would not be valid to just look at tile #1. If it turns out to be L, you will only know that the original sequence could have been either LG or LL. If the original sequence is LG, there is at least one G in the artwork, but if the original sequence is LL, there are no Gs. So 1 would not be a valid solution.

Note that 1 2 is also a valid solution, because tile #2 already provides all the information you need. 1 2 3 is not a valid solution, because it uses too many tiles.

In sample case #2, the artwork must consist of only one tile: either G or L. Looking at that tile will trivially tell you whether or not the artwork has a G in it.

In sample case #3, which would not appear in the Small dataset, the artwork must be either GG, GL, LG, or LL. You can only look at one tile, and neither of them on its own is enough to answer the question. If you see L for tile #1, you will not know whether the artwork is LG or LL, so you will not know whether any Gs are present. If you see L for tile #2, you will not know whether the artwork is GL or LL, so you will not know whether any Gs are present.

Sample case #4 is like sample case #3, but with access to one more tile. Now you can just look at the entire artwork.

In sample case #5, there are eight possible original sequences, and they would produce the following artwork:

  • Original sequence GGG: GGGGGGGGG
  • Original sequence GGL: GGGGGGGGL
  • Original sequence GLG: GGGGLGGGG
  • Original sequence GLL: GGGGLLGLL
  • Original sequence LGG: LGGGGGGGG
  • Original sequence LGL: LGLGGGLGL
  • Original sequence LLG: LLGLLGGGG
  • Original sequence LLL: LLLLLLLLL

One valid solution is to look at tiles #2 and #6. If they both turn out to be Ls, the artwork must be all Ls. Otherwise, there must at least one G. Note that 1 2 would not be a valid solution, because even if those tiles both turn out to be Ls, that does not rule out an original sequence of LLG. 6 2 would be a valid solution, since the order of the positions in your solution does not matter.


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1010, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
void fre()
{
	freopen("c://test//input.in", "r", stdin);
	freopen("c://test//output.out", "w", stdout);
}
LL k, c, s;
void solve()
{
	int p = 0;
	while (p < k)
	{
		LL pos = 0;
		for (int i = 0; i < c; ++i)
		{
			pos = pos*k + min((LL)p, k - 1);
			++p;
		}
		printf("%lld ", pos + 1);
	}puts("");
}
int main()
{
	fre();
	scanf("%d", &casenum);
	for (casei = 1; casei <= casenum; ++casei)
	{
		scanf("%lld%lld%lld", &k, &c, &s);
		printf("Case #%d: ", casei);
		if (s*c < k)puts("IMPOSSIBLE");
		else solve();
	}
}
/*
【trick&&吐槽】
手动模拟找规律其实是解决构造问题很行之有效的方法。

【题意】
https://code.google.com/codejam/contest/6254486/dashboard#s=p3
给你一个K,表示我们的基础图形(其位于复杂度1下),
图形包括'L'和'G'两种字符。
对于在复杂度i下的图形,在其变化为复杂度i+1图形的时候
'L'会变成复杂度为1的基础图形
'G'会变为长度为K的全'G'图形

我们现在得到了复杂度为C的图形。然而并不知道这个图形是什么。
不过,我们现在拥有S次机会,可以知道复杂度为C图形的最多S个位置的图形是什么('L'还是'G')
问你能否选择S个位置,判断出原始图形中是否有'G'存在

1 ≤ T ≤ 100.
1 ≤ K ≤ 100.
1 ≤ C ≤ 100.
1<=S<=K
K^C ≤ 1018.
(小数据S==K)

【类型】
构造 找规律

【分析】
这题的小数据完全是送分的。
对于小数据,我们可以发现,原来第i个位置(i为0base from 0~K-1),
在复杂度2下,会变为i*K+i
在复杂度3下,会变为(i*K+i)*K+i
我们只要这样映射下去,最后直接处理这就可以找到答案。
然而,更进一步,其实我们只要输出前K个位置就可以了。
因为它们要不就全部为G,要不就为第一行,不论是哪种情况,我们都可以还原整个序列。

======================================================================
而我们要如何处理大数据呢?
事实上——
K作为原串长度,C作为原串扩展的次数,S为我们可以查看的位置
只要K<=C*S,就一定有解。

举例说,原串的长度K为2,变换的次数C为2,查看的位置S为1。
答案为yes,我们只要查看第二个位置就可以了。

为什么呢?
长度K为2的原始串有4个
LL,LG,GL,GG,
它们经过变换后会相应变为——
LLLL,LGGG,GGGL,GGGG
果然,我们只要查看第二个位置就可以。

原始串的长度越少,我们需要的查看次数就越少,这个很好理解。
然而,变换的次数越多,我们需要查看的次数同样也越少,这个是为什么呢?

---------------------------------------------------------------------
设第一次的串长度为n,第i个位置的为a[i]

经过一次变换之后,这个字符串会变为n段,每段各有n个字符。
如果是在第二层的字符串上查询,我们可以查询第1段字符中的第2个。
如果这个字符是G,显然已经结束。
如果这个字符不是G,显然它能够说明a[1]!='G'且a[2]!='G',一下子验证了2个位置

经过两次变换之后,这个字符串会变为n*n*n的结构
如果我们是在第三层的字符串上查询,我们可以查询第1大段中第2小段中的第3个字符。
如果这个字符是G,显然已经结束。
如果这个字符不是G,显然它能说明a[1]!='G'且a[2]!='G'且a[3]!='G'

于是——
C*S是我们的验证能力,C*S>=K答案即为Possible,我们即可以根据之前找到的规律构造具体实现方案。
详细参照代码

【时间复杂度&&优化】
O(c+s+k)

*/


你可能感兴趣的:(构造,Codejam,观察找规律,题库-google)