集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里。比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸。
本题给定一张不相容物品的清单,需要你检查每一张集装箱货品清单,判断它们是否能装在同一只箱子里。
输入格式:
输入第一行给出两个正整数:N (≤10^4 ) 是成对的不相容物品的对数;M (≤100) 是集装箱货品清单的单数。
随后数据分两大块给出。第一块有 N 行,每行给出一对不相容的物品。第二块有 M 行,每行给出一箱货物的清单
格式如下:
K G[1] G[2] … G[K]
其中 K (≤1000) 是物品件数,G[i] 是物品的编号。简单起见,每件物品用一个 5 位数的编号代表。两个数字之间用空格分隔。
输出格式:
对每箱货物清单,判断是否可以安全运输。如果没有不相容物品,则在一行中输出 Yes,否则输出 No。
输入样例:
6 3
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
4 00001 20004 00002 20003
5 98823 20002 20003 20006 10010
3 12345 67890 23333
输出样例:
No
Yes
Yes
作者: CHEN, Yue
单位: 浙江大学
时间限制: 400 ms
内存限制: 64 MB
代码长度限制: 16 KB
这道题效率最高的方法应该是使用十字链表
但是懒癌晚期…
思路是一样的,最下面修改前的代码思路更为清晰一些
主要思路:
建立一个与某物品不相容的清单
如给定6对互不相容的物品:
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
将一对中第一个重复的合并,得到:
20001 20002
20003 20004 20001
20005 20006 20004
20004 20006
然后对给定的一箱物品检查有无相排斥的物品出现就可以了。
/*附:
其实最初想法是将一对互斥物品的左右两个物品都建立数组保存的
即得到:
20001 20002 20003
20002 20001
20003 20004 20001
20004 20003 20005 20006
20005 20006 20004
20006 20005 20004
但是想想这样赋值两次是不是虽然看起来更稳妥,但是完全没必要的啊。只记录一对中的第一个的不相容物品就可以达到检测的目的了。
(语言表达能力和代码逻辑都不太好…大家尽量自己悟一下)
继续…
第一次尝试建立的数组过大,出现段错误
改的时候随便给数组赋了个2,代码绝对是错的,居然AC了…瞎猫碰上死耗子冠军…
(老师!测试点有空子可钻!!)
但是我不死心,对代码进行了改进。
两次代码比较后发现!
增加一次qsort后代码效率并没有太大变化
快速排序是好东西!
用好排序很有用!
耗时29ms!满意!应该是比其他方法都快的
#include
#include
int cmp(const void *a,const void *b)//升序(其实无球的所谓)
{
int *p=(int *)a,*q=(int *)b;
return *p-*q;
}
int main()
{
int M,N,i,j,k,l,Index[100000][2]={0,0},Num,Max,a1,a2,Flag,K,t;
/*关于Index[][]
*Index[k][0]:即与编号为k的货物 互不相容的货物 在List数组中存放的位置
*Index[k][1];即List中存放的 与编号为k的货物互不相容的 货物编号数量
*例:Index[k][0]==i Index[k][1]==j
*即为:与 编号为k的货物 互不相容的j个货物存放在 List[i]中。*/
scanf("%d %d",&N,&M);
int Conflict[N][2];//存放N对互不相容的货物编号
for(Max=0,Num=0,i=0 ; i<N ; i++)
{
scanf("%d %d",&Conflict[i][0],&Conflict[i][1]);
if( Index [ Conflict [i] [0] ] [1]++ == 0 )//为避免数组越界,尽量节省空间,记录下共需要建立多少个货物的不相容清单(Num
Index [ Conflict [i] [0] ] [0] = Num++;
Max = Max < Index[ Conflict [i] [0] ] [1] ? Index[ Conflict [i] [0] ] [1] : Max;//不相容货物最多有几个(Max
}
qsort(Conflict,N,sizeof(Conflict[0]),cmp);//以一对中的第一个货物编号排序,使相同编号的靠在一起
int List[Num][Max];//存放不相容的清单
for(i=0,j=0,k=0 ; i<N ; i++)//存放
{
if( Conflict [i] [0] == Conflict [i+1] [0] )
{
List [j] [k++] = Conflict [i] [1];
}
else
{
List [j] [k++] = Conflict [i] [1];
Index[ Conflict [i] [0] ] [1] = k;
Index[ Conflict [i] [0] ] [0] = j++;
k=0;
}
}
for(i=0 ; i<M ; i++)
{
scanf("%d",&K);
int G[K],T[100000]={0};
for(j=0 ; j<K ; j++)//将第i箱货物赋1
{
scanf("%d",&G[j]);
T[G[j]]++;
}
for(Flag=0,j=0 ; j<K && Flag==0 ; j++)
for(k=0 ; k < Index[G[j]][1] && Flag==0 ; k++)//检测有没有互不相容的货物
if( T[List[ Index[G[j]][0] ][k]] > 0 )
Flag=1;
printf("%s\n",Flag ? "No" : "Yes");
}
return 0;
}
#include
int main()
{
int M,N,i,j,k,l,Count[100000]={0},a1,a2,Flag,K;
scanf("%d %d",&N,&M);
int List[100000][2];
/*此处错误:数据量大的时候不可能保证最多仅两个不相容物*/
for(i=0 ; i<N ; i++)
{
scanf("%d %d",&a1,&a2);
List[a1][Count[a1]++] = a2;
}
for(i=0 ; i<M ; i++)
{
scanf("%d",&K);
int G[K],Temp[100000]={0};
for(j=0 ; j<K ; j++)
{
scanf("%d",&G[j]);
Temp[G[j]]++;
}
for(Flag=0,j=0 ; j<K && Flag==0 ; j++)
for(k=0 ; k<Count[G[j]] && Flag==0 ; k++)
if( Temp[List[G[j]][k]] > 0 )
Flag=1;
printf("%s\n",Flag ? "No" : "Yes");
}
return 0;
}