1094 sorting it all out

作者&投稿:贰璐 (若有异议请与网页底部的电邮联系)
1094:Sorting It All out~

/*
解题思路:
开始想用拓扑排序,后来失败了很多次。参考了下别人的思路,用二维数组的方法处理

如果A<B B<C 那么可以判定A<C;如果A<B B<C B<D可以判定A<C A<D
即每一次读取一个条件可以根据以前的条件做出所有可以得出字符间两两的大小
用什么来存储呢?我们想到了图论中的最短路径,可以用二维数组b[][]来存储

令b[i][j]表示i是否小于j,即b[i][j]==1表示已知i<j,b[i][j]==0表示没有数据
当得到一个关系x < y时:
若存在b[y][x]==1。则产生冲突。
否则,对于所有的b[i][x]==1,都赋值b[i][y]=1;对于所有的b[y][j]==1,都赋值b[x][j]=1。
这样处理之后,可以得到的b[][]数组既是已知的所有直接和间接的小于关系,判断排序成功也就容易了。
那么如何才能排序呢?举个例子A<C C<B通过上面的判断可以得出数组:
ABC
A011 =2
B000 =0
C010 =1
可以看出可以按照b[]的加合来判断具体的大小,那么我们就引进count[]来作为第N个数的权值
只要count[]取之能从0-n(表示有n个字母)且唯一,那么我们就可以得出ORDER的结论
具体解决代码见下,我想注解应该比较明确了
*/
#include
#include
#include
int count[30]; //用来记录每个字母的权值,权值约大表示越小
int cmp(const void *a,const void *b)//比较函数,表示按照count的顺序排列cmp
{
return count[*(int*)a]-count[*(int*)b];
}


int main()
{
int n,m;
int b[30][30];//用来储存判断字母大小的数组

int idx[30];//字母大小的索引,表示该数组从后往前是字母的排序
//如idx[0]=1,idx[1]=0表示第一个位置是0+A,第二个位置是1+A,即AB
int ordered;//表示有唯一排序,且记录唯一时读取的条件数
int conflicted;//用来表示有冲突,并且记录冲突时读取的条件数
int i,j,k;
char s[30],x,y;

while(scanf("%d%d",&n,&m),n+m)
{
//初始化
memset(b,0,sizeof(b));
memset(count,0,sizeof(count));//先将b和count初始化为0
ordered=conflicted=0; //将2个标志初始化为0
for(i=0;i<n;i++) idx[i]=i;//将权值记录器初始化
//开始从第一条数据读取
for(k=1;k<=m;k++)
{
scanf("%s",s);
if(ordered || conflicted) continue; //如果2个标志已有记录(唯一或冲突),不再继续处理
x=s[0]-'A'; y=s[2]-'A';
if(b[y][x])//判断是否冲突,如果有冲突,记录冲突的位置,并不再继续处理
{
conflicted=k;
continue;
}
//更新数据查询表
if(b[x][y]) continue; //判断是否已经有该条件,如果数组中已经存储,这不再继续
b[x][y]=1; //将数组中x<y的位置标志为1
count[x]++; //权值加1
for(i=0;i<n;i++)//更新数组结合以前的推论,得出每个字母比较矩阵
{
if(b[i][x])
if(!b[i][y]) b[i][y]=1,count[i]++;
if(b[y][i])
if(!b[x][i]) b[x][i]=1,count[x]++;
}
//检查是否唯一排序,当然可以只用一个count进行处理但是代码麻烦
qsort(idx,n,sizeof(int),cmp); //idx根据count的顺序进行排列
for(i=0,j=1;i<n && j;i++) //判断是否唯一排列
if(count[idx[i]]!=i) j=0;
if(j) ordered=k;
}
//输出结果,不多解释
if(conflicted)
{
printf("Inconsistency found after %d relations.
",conflicted);
}
else if(ordered)
{
printf("Sorted sequence determined after %d relations: ",ordered);
for(i=n-1;i>=0;i--) printf("%c",idx[i]+'A');
printf(".
");
}
else
{
puts("Sorted sequence cannot be determined.");
}
}

return 0;
}

就让他去吧!

so let it all out 所以就让它去吧

程序这么长,难得看啊,主要是数组溢出问题,看看程序
for(i=1;i<=n;i++){
if(relation[i][0]+relation[0][i]!=0)
这里,因为n是你在程序外输入的一个数,而int relation[30][30];的最大范围只有30,那么,当输入的n大于30时就会出错了。
在topsort函数里还有很多处诸如此类的数组溢出错误。

当你输入的n小于30时,就会出现下面的数组溢出错误啊。数组溢出不止一处哦。
诸如 if(relation[y-'A'+1][x-'A'+1] ==1)

if(relation[x-'A'+1][y-'A'+1] != 1){
relation[x-'A'+1][y-'A'+1] = 1;
relation[y-'A'+1][0]++;//y入度
relation[0][x-'A'+1]++;//第一行表示相应的出度

自已慢慢检查吧,你的程序是做什么的,我看不懂,看肯定是数组溢出错。

请写出题目地址


富蕴县17644814160: 1094:Sorting It All out -
剧服归芪: /* 解题思路:开始想用拓扑排序,后来失败了很多次.参考了下别人的思路,用二维数组的方法处理 如果A<B B<C 那么可以判定A<C;如果A<B B<C B<D可以判定A<C A<D 即每一次读取一个条件可以根据以前的条件做出所有可以得出字符间...

富蕴县17644814160: sql 错误代码1094 unknow thread id 怎么解决 -
剧服归芪: 从文件服务器中大量存取数据,文件服务器集中管理系统共享资源.但是如果文件服务器或文件服务器的硬盘出现故障,数据就会丢失,所以,我们在这里讲解的容错技术是针对服务器、服务器硬盘和供电系统的.

富蕴县17644814160: Linux安装脚本g++编译报错 -
剧服归芪: 你输入的命令:-o /home/r910/softwares/NIKS/jellyfish_sorting_key/jellyfish_sorting_key.cc不对吧,-o后面加目标文件, 空格后再加源文件,像这样 -o a.out a.c

富蕴县17644814160: GB 1094 电力变压器 一共分为几个部分 -
剧服归芪: GB 1094 电力变压器 是中国发布的国家标准,主要参照IEC60076.目前,IEC60076共有23个分标准,而GB 1094也已经在讨论第18部分(变压器频率响应测量).所以,目前你能看到的GB1094应该共有18个分标准.

富蕴县17644814160: 用C语言,随机输入10个整数,用冒泡排序法对这些整数进行从小到大排序,输出排序前和排序后的数的顺序. -
剧服归芪: C语言随机输入10个整数的源代码如下: #include"stdio.h" void fun(int a[]) { int i,j,t; for(i=0;i<9;i++) for(j=i+1;j<10;j++) if(a[i]>a[j]) {t=a[i];a[i]=a[j];a[j]=t;} } void main() { FILE *wf; int a[10]; int b[10]={9,10,11,12,1,2,3,4,0,1}; int c[10]={1,2,3,4,13,14,15,16,...

富蕴县17644814160: oracle使用存储过程、包来实现冒泡、选择、快速排序,需要完成相应代码.如下 -
剧服归芪: 建用户和授权要用DBA 最简单得建用户:create user 用户名 identified by 密码 用户解锁 alter user 用户名 account unlock(不解锁无法登陆) 授权用 grant 建完用户首先要授权登陆权限 grant create session to 用户名 授权可以授权给角色和用户 也可以把角色授权给角色和用户 其他得类似 创建表得权限类似如下格式:grant create table to 用户

富蕴县17644814160: 深圳违章代码1094是指什么违章行为 -
剧服归芪: 违章是否扣分是根据代码第2位数来区别的:如1039,第2位数为0不需扣分,如1102第2位数为1的则扣1分,如1228则扣2分,如1301则扣3分,如1625则扣6分,而扣12分的第2位数则为7.

富蕴县17644814160: 最新1094次列车时刻表 -
剧服归芪: 成都东 发:11:02 K1091/K1094次34小时32分 深圳东 到:21:34 站次 站名 到达时间 开车时间 停车时间 运行时间1 成都东 起点站 11:02 - -2 南充 13:09 13:13 4分 2小时7分钟3 蓬安 13:40 13:44 4分 2小时38分钟4 营山 13:56 14:07 11分 2小时54...

富蕴县17644814160: 1094年的常州陨石的来历 -
剧服归芪: 天空中发出像打雷一样的巨响,原来是一颗大 星,几乎像月亮一样,在东南方出现.不一会而又震响了一声,移到西南方去了.又一震响后,星星就落在宜兴县一个姓许的人家的院子里,远处近处的人都看到了,火光明亮照天,许家的篱笆都烧毁了. 这时火熄灭了,看地面上有一个像茶杯大小的洞穴,很深.往下看,星星在洞穴里面,发着微弱的光.过了好久,才渐渐暗下来,还热得不能靠近.又过了很长时间,掘开那个洞穴,有三尺多深,才得到一块圆形的石头,还很热,它大小像拳头一样,一头略微尖些,颜色像铁,重量也像铁似的. 常洲的太守郑伸得到它,送到润州金山寺保存.

富蕴县17644814160: 1094次列车时刻表 -
剧服归芪: T740宁波到南京西,9:58出发,12:02到杭州东下,历时2小时,软座37,没有硬座. K197/K200上海到厦门,12:25从杭州东站出发到厦门. 里程1094,硬座140元,硬卧(中)248元.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网