• 洛谷 P1347 【排序】


    这篇题解没有用拓补排序 (嗐 菜就直说)

    个人感觉这道题拓补排序没有变种(Floyd)好写吧,思维难度也低一点(亲眼目睹机房dalao这道题拓补排序调了很久)。


    吐槽结束,开始正题~

    对于这道题为什么可以用(Floyd),应该就是传递性了。当(A>B)时,(B>C),那么现在肯定有(A>C)了,想想原来的(Floyd),是不是也有点传递性的味道。这样一来,我们就可以在已知一部分条件的情况下,求出其他值的大小关系,最后看是不是每个数都跟其他的每一个数确认了关系,如果是,那么这个数的位置也就出来了,也就是排好序了,不是,就输入下一个数,直到满足每个数都跟其他的每一个数确认了关系。如果还是不能很好理解的话,可以看下代码来理解。

    具体代码里面有两个可以优化的地方,但是数据太水,不加也能过。

    #include <bits/stdc++.h>
    using namespace std;
    int n , m , T;
    int dis[30][30];
    int id(char x){	//字母转化为数字 
    	return x - 'A' + 1;
    }
    int main(){
    	cin >> n >> m;
    	T = m;
    	for(int i = 1; i <= n; i++) dis[i][i] = 1;	//这里统一认为自己大于自己(方便一点) 
    	while(T--){
    		char a , b , c;
    		cin >> a >> b >> c;
    		if(dis[id(a)][id(c)]){	//处理矛盾 
    			printf("Inconsistency found after %d relations." , m - T);
    			return 0;
    		}
    		dis[id(c)][id(a)] = 1;	//c大于a 
    		for(int k = 1; k <= n; k++)
    			for(int i = 1; i <= n; i++)
    				for(int j = 1; j <= n; j++)
    					dis[i][j] = dis[i][j] || (dis[i][k] && dis[k][j]);	//变种Floyd i>j和i>k>j都可以表明i>j 
    		/*
    		for(int i = 1; i <= n; i++)	上面的那个Floyd可以这样优化,因为我们每次只涉及到了a和c,所以只用它们两个更新其他的就可 
    			for(int j = 1; j <= n; j++)
    				dis[i][j] = dis[i][j] || (dis[i][id(a)] && dis[id(a)][j]);
    		for(int i = 1; i <= n; i++)
    			for(int j = 1; j <= n; j++)
    				dis[i][j] = dis[i][j] || (dis[i][id(c)] && dis[id(c)][j]);
    		*/
    		int f = 1;
    		for(int i = 1; i <= n; i++){
    			int x = 0;
    			for(int j = 1; j <= n; j++)
    				if(dis[i][j] || dis[j][i]) x++;	//如果确定了与其他n个数(包括自己)的关系,那么就可以确定这个数的位置 
    			if(x != n) f = 0;
    		}
    		if(f){
    			printf("Sorted sequence determined after %d relations: " , m - T);
    			for(int k = 1; k <= n; k++){	//这里应该也能优化,设立一个vis数组,存储当前这个数的位置,如果这个数字的位置早确定了,那么就不算这个数,直接算下一个数 ,具体优化操作不想写了, 原谅我的懒惰T_T 
    				for(int i = 1; i <= n; i++){
    					int x = 0;
    					for(int j = 1; j <= n; j++) 
    						if(dis[i][j]) x++;	//最小的数只会大于一个数(它自己),第二小的数只会会大于两个数,以此类推 
    					if(x == k) cout << (char)(i + 'A' - 1);	//如果符合当前的排名,输出 
    				}
    			}
    			cout << ".";	//记得这个句号(6泪) 
    			return 0;
    		}
    	}
    	printf("Sorted sequence cannot be determined.");
    	return 0;
    }
    

    双倍经验时间:

    P2419

  • 相关阅读:
    Pandas学习整理与实践
    数据描述性统计整理
    关于购置硬盘的相关注意点
    福大软工 · 最终作业
    福大软工 · 第十二次作业
    Beta冲刺 (7/7)
    Beta冲刺 (6/7)
    深度剖析Vue中父给子、子给父、兄弟之间传值!
    mysql 增删改插
    前端必学TypeScript之第一弹,st基础类型!
  • 原文地址:https://www.cnblogs.com/bzzs/p/13220482.html
Copyright © 2020-2023  润新知