SGU - 355 - Numbers Painting (贪心)

355. Numbers Painting
Time limit per test: 0.25 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



Dr. Vasechkin wants to paint all numbers from 1 to  N in such a way that if number  A is divisible by number  B, numbers  A and  B have different colors.

Help Dr. Vasechkin to find such a painting, where the number of the colors used is minimal.

Input
The input contains integer number  N ( ). 

Output
Write the number of the colors  M in the desired painting in the first line of the output. In the second line of the output write the desired painting of numbers from 1 to  N. The used colors should be represented by numbers from 1 to  M. If there are several solutions, choose any of them.

Example(s)
sample input
sample output
12
4
1 2 2 3 2 3 2 4 3 3 2 4




Online Contester Team © 2002 - 2010. All rights reserved.



思路:给1到N的数字涂颜色,使得颜色数尽可能少,贪心.....

首先可以看出1可以整除任何数,即任何数都不可以与1相同颜色,然后可以发现互质的一群数可以相同颜色,而当两个数有大于1的约数时可以判断这两个数不同颜色,慢慢可以看出1,2,4,8,16,32......这些数的颜色都不一样,到32为止有6种颜色,可以验证是最小的颜色种类使用数,于是归纳出解决方案为一个筛法(与素数筛类似,具体看代码)

注意打印数字颜色的方法,对于数字i,从i~n*i(n*i为小于N的最大数),对于每个区间(m, m*2-1)取一种颜色(m为i的倍数).......(自己想想为什么,有别的好的想法可以讨论)


AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int color[10005];

int main() {
	int N;
	while(scanf("%d", &N) != EOF) {
		int ans = 1;
		for(int i = 2; i <= N / 2 + 1; i++) {	//算出最小的颜色种类数 
			int tmp = 1;
			for(int j = i; j <= N; j *= 2) {
				tmp++;
			}
			if(tmp > ans) ans = tmp;
		}
		
		memset(color, 0, sizeof(color));	//记录每个数字的颜色 
		color[1] = 1;
		for(int i = 2; i <= N; i++) {
			if(color[i] == 0) {
				int c = 2;
				int t = i;
				for(int j = i; j <= N; j += i) {
					if(j >= t * 2) c++, t *= 2;
					color[j] = c;
				}
			}
		}
		
		printf("%d\n", ans);		//输出结果 
		for(int i = 1; i < N; i++) printf("%d ", color[i]);
		printf("%d\n", color[N]);
	}
	return 0;
}














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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值