• P2474 [SCOI2008]天平


    不得不说人家省选题目出的就是有水平

    开始一直没有搞懂题目到底什么意思 这句话是关键:只有结果保证惟一的选法才统计在内

    也就是左边有很多种可能性 右边选出来有很多种可能性 必须是左边严格大于右边(可能性不相交)c1++

    同理 那这样就好理解了 因为是大小关系 想到差分约束 因为我们要严格大于或者小于 所以要求最长路和最短路

    之后枚举就行

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    using namespace std;
    int n,s1,s2;
    int dx[55][55],dn[55][55];
    int main()
    {
        scanf("%d%d%d",&n,&s1,&s2);
        char a[60];
        for(int i=1;i<=n;i++){
            scanf("%s",a);
            for(int j=0;j<strlen(a);j++){
                if(a[j]=='=' || i==j+1){
                    dn[i][j+1]=0;dx[i][j+1]=0;
                } else if(a[j]=='+') {
                    dx[i][j+1]=2;  dn[i][j+1]=1;  //i-j<=2; i-j>=1;
                }else if(a[j]=='-'){
                    dx[i][j+1]=-1; dn[i][j+1]=-2; //i-j<=-1;i-j>=-2;
                }else {
                    dx[i][j+1]=2;  dn[i][j+1]=-2; //i-j<=2; i-j>=-2;
                }
            }
        }
        
        
        for(int k=1;k<=n;k++)            //Floyd
            for(int i=1;i<=n;i++) {  
                if(i==k) continue;    
                for(int j=1;j<=n;j++){
                    if(i==k || i==j) continue;
                    dx[i][j]=min(dx[i][j],dx[i][k]+dx[k][j]);//上界求最短路
                    dn[i][j]=max(dn[i][k]+dn[k][j],dn[i][j]);//下界求最长路 
                }
            }
        
        
        int c1=0,c2=0,c3=0;
        for(int i=1;i<=n;i++){                 //暴力枚举所有可能性  
            if(i==s1 || i==s2) continue;
            for(int j=1;j<i;j++){
                if(j==s1 || j==s2) continue;
                if(dn[s1][i]>dx[j][s2] || dn[s2][i]>dx[j][s1])
                    c1++;      //s1-i的最小值大于j-s2的最大值==>s1+s2>i+j
                if(dn[i][s1]>dx[s2][j] || dn[i][s2]>dx[s1][j])
                    c3++;      //同理:i-s1>s2-j ==> i+j>s1+s2
                if((dn[s1][i]==dx[s1][i] && dn[j][s2]==dx[j][s2] && dn[s1][i]==dn[j][s2]) || 
                (dn[s1][j]==dx[s1][j] && dn[i][s2]==dx[i][s2] && dn[s1][j]==dn[i][s2]))
                    c2++;     //关系确定且满足的点 
            }
        }
        printf("%d %d %d",c1,c2,c3);
        return 0;
    }
  • 相关阅读:
    Android服务之bindService源代码分析
    [iOS 高级] iOS远程推送与本地推送大致流程
    redis集群
    面试你之前,我希望在简历上看到这些!
    解决安卓出现导入第三方包反复的错误
    【PA2012】【BZOJ4289】Tax
    Spark jdbc postgresql数据库连接和写入操作源代码解读
    Java中hashcode的理解
    CvArr、Mat、CvMat、IplImage、BYTE转换
    CSDN日报20170413 ——《天天写业务代码的那些年,我们是怎样成长过来的》
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/16187802.html
Copyright © 2020-2023  润新知