[Luo valley P3940]: packet (greedy + disjoint-set)

Topic Portal


Title Description

Small $ C $ in the understanding of the information she needed, so that the rabbits adjusted to the proper position. Small $ C $ prepared to give the rabbit were divided into several groups to feed carrots to the rabbits the right to eat.
At this time, n-$ $ rabbits in a certain order in a row, the $ I $ rabbits color $ a_i $. Since the order already has been adjusted, so that each group should be a sequence of contiguous stretch .
In the former group, small $ C $ discovered a pattern: some rabbit will twenty-two conflict. And, two rabbits conflicts will occur if and only if representatives of their color value sum of the square of a positive integer. For example, contradictory $ 1 $ color rabbit and $ 2 $ color rabbit will not happen, because the $ 3 $ is not any positive integer squared; and $ 1 $ color rabbit but it will, and $ 3 $ color rabbit conflict, because the $ 4 = 2 ^ 2 $.
Small $ C $ believes that as long as conflicts within a group is not too big on the line. Thus, small $ C $ defines a group of conflict value $ k $, where this group represents, at least into this group again $ k $ small groups; each small group need not be contiguous sequence for some, but need to make between any two rabbits in each group were small conflicts do not occur.
$ C $ small claims, the largest group of contradictions contradictory value $ k $ does not exceed $ K $ on it. Of course, such a grouping method may be many months; To make the grouping has become more harmonious, less $ C $ wondering, in the case to ensure that a minimum number of packets, the smallest lexicographical program is. Can you help her?
Lexicographically smallest solution means, spaced apart locations in sequence packet, i.e. the presence of all rabbits and $ I $ $ i + $ 1 position in the different groups.


Input Format

The first input line two positive integers $ n, K $.
Input line 2 $ n $ positive integer, the number of $ I $ $ I $ denotes rabbits color $ a $.


Output Format

The first $ 1 $ output line a positive integer $ m $, rabbits need to be divided into at least how many teams as you.
Output $ 2 $ rows $ m-1 $ a small to a large integer array, the $ I $ number $ S_I $ represents $ S_I $ and $ s_ {i + 1} $ in your program was to be assigned two teams. If $ m = 1 $, please outputs a blank line.


 

Sample

Sample input 1:

5 2
1 3 15 10 6

Sample output 1:

2
1

Sample input 2:

319 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319

样例输出2:

6
7 31 71 127 199


 

数据范围与提示

样例1解释:

如果将五只兔子全部分到同一个小组的话,那么$(1,3)(3,6)(6,10)(10,15)(1,15)$均不能分到同一个小团体;因为最多分成两个小团体,所以为了满足前4对限制,只能分为$\{\{1,6,15\},\{3,10\}\}$,但此时不满足$(1,15)$,所以不存在一种组数为$1$的方案满足全部限制。
如果将五只兔子分为两个小组的话,一种字典序最小的可行的分组方案是$\{1\},\{3,15,10,6\}$,此时第二组内的小团体数量不超过$2$的一种分法是$\{\{3,10\},\{15,6\}\}$。

数据范围:

$K=1||2$

$n\leqslant 131076$

$a_i\leqslant 131072$


 

题解

对于$K=1$:

 测试点$1$:$n=2$

  直接判一下两数值和是否为完全平方数。

  是就$puts("2$ \ $n1");$,不是就$puts("1$ \ $n");$。

  时间复杂度:$\Theta(1)$。

  期望得分:$4$分。

  总得分:$4$分。

 测试点$2$:$n=4$

  手动讨论所有情况即可。

  时间复杂度:$\Theta(1)$。

  期望得分:$4$分。

  总得分:$8$分。

 测试点$3$:$n=16$

  暴力搜索,可以得到所有的分组情况,一个一个验证就好了。

  时间复杂度:$\Theta(2^n\times n^2)$。

  期望得分:$12$分。

  总得分:$12$分。


代码时刻

测试点$1$:

#include<bits/stdc++.h>
using namespace std;
int a[131073];
int main()
{
	int n,K;
	scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	if(K==1)
	{
		if(n==2)
			if((int)sqrt(a[1]+a[2])*(int)sqrt(a[1]+a[2])==a[1]+a[2])puts("2\n1");
			else puts("1\n");
	}		
	return 0;
}

测试点$2$:

#include<bits/stdc++.h>
using namespace std;
int a[131073];
bool asksqr(int x,int y){return (int)sqrt(x+y)*(int)sqrt(x+y)==x+y?0:1;}
void judge0()
{
	if(asksqr(a[1],a[2])&&asksqr(a[1],a[3])&&asksqr(a[1],a[4])&&asksqr(a[2],a[3])&&asksqr(a[2],a[4])&&asksqr(a[3],a[4])){puts("1\n");exit(0);}
}
void judge1()
{
	if(asksqr(a[2],a[3])&&asksqr(a[2],a[4])&&asksqr(a[3],a[4])){puts("2\n1");exit(0);}
	if(asksqr(a[1],a[2])&&asksqr(a[3],a[4])){puts("2\n2");exit(0);}
	if(asksqr(a[1],a[2])&&asksqr(a[1],a[3])&&asksqr(a[2],a[3])){puts("2\n3");exit(0);}
}
void judge2()
{
	if(asksqr(a[3],a[4])){puts("3\n1\n2");exit(0);}
	if(asksqr(a[2],a[3])){puts("3\n1\n3");exit(0);}
	if(asksqr(a[1],a[2])){puts("3\n3\n3");exit(0);}
}
void judge3(){puts("4\n1\n2\n3");exit(0);}
int main()
{
	int n,K;
	scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	if(K==1)
	{
		if(n==4)
		{
			judge0();
			judge1();
			judge2();
			judge3();
		}
	}		
	return 0;
}

测试点$3$:

#include<bits/stdc++.h>
using namespace std;
int n,K;
int a[131073];
int ans[131072],cnt;
bool asksqr(int x,int y){return (int)sqrt(x+y)*(int)sqrt(x+y)==x+y?1:0;}
bool judge()
{
	for(int i=1;i<=cnt;i++)
		for(int j=ans[i-1]+1;j<ans[i];j++)
			for(int k=j+1;k<=ans[i];k++)
				if(asksqr(a[j],a[k]))return 0;
	for(int i=ans[cnt]+1;i<n;i++)
		for(int j=i+1;j<=n;j++)
			if(asksqr(a[i],a[j]))return 0;
	return 1;
}
void print()
{
	printf("%d\n",cnt+1);
	for(int i=1;i<=cnt;i++)
		printf("%d ",ans[i]);
}
void dfs(int x,int l,int w)
{
	if(x==w){if(judge()){print();exit(0);}return;}
	for(int i=l;i<n;i++)
	{
		ans[++cnt]=i;
		dfs(x+1,i+1,w);
		cnt--;
	}
}
int main()
{
	scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	if(K==1)
	{
		for(int i=0;i<n;i++)dfs(0,1,i);
	}
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/wzc521/p/11297146.html