3.集合分组(device.c/cpp)
[问题描述]
现有K个整数集合,第i个集合有Sumi个元素。
集合中的数都为正数,且不大于N。
现有定义集合A与集合B相似;
1.B与A相似;
2.将A集合删去一个元素,或更改一个元素的值之后A集合与B集合相等。
现要将K个集合分成至多M组(M>N),使得每一组内的集合互不相似。要求你给出一种合法的方案。如果无解请输出“impossible”。
[输入格式]
输入文件第一行有三个数N,K,M,意义如题目所述。
接下来有K行,每行第一数Sum表示序列长度。之后Sum个数为些集合的元素。
[输出格式]
输出文件有K个数,表示每个集合(按输入顺序)被分到的组的编号(1~M)。
[样例输入]
8 20 12
5 1 3 5 6 4
5 1 3 5 6 3
4 5 6 3 3
4 5 6 3 4
4 4 6 5 8
4 7 7 7 7
3 7 7 7
2 2 2
3 2 2 7
3 1 2 3
3 1 2 4
10 1 2 3 4 56 7 8 7 6
10 8 7 6 5 43 2 1 2 1
20 1 2 3 4 56 7 8 1 2 3 4 5 6 7 8 1 3 5 7
5 4 6 4 6 4
5 6 4 6 4 6
6 6 6 6 6 6 6
3 6 6 6
1 1
1 2
[样例输出]
2
1
9
1
6
2
4
5
3
7
8
5
4
8
7
9
1
1
2
3
[数据范围]
对于30%的数据满足N≤10,M≤2,K≤10。
对于100%的数据满足N≤100,M≤100,K≤50000,Sum≤100。
数论题,这道题是春哥给我们讲的。根据这里相似的定义,如果两个集合相似,则集合和的差大于0且小于n,所以两个集合和对(n+1)取模如果相同,则必定不相似;同样的如果相似,则模一定不相同。。。这个证明下午来写。。。。
#include <iostream>
using std::cout;
long n;long k;long m;
int main()
{
freopen("device.in","r",stdin);
freopen("device.out","w",stdout);
scanf("%ld%ld%ld",&n,&m,&k);
for (long i=1;i<k+1;i++)
{
long t;scanf("%ld",&t);
long tt=0;long ttt;
for (long i=1;i<t+1;i++)
{
scanf("%ld",&ttt);
tt += ttt;
}
printf("%ld\n",(tt%(n+1))+1);
}
}