USACO08JAN && 洛谷P2419 牛大赛

  果然啊,提高— 就是可以瞎搞的东西啊 。

题目描述
N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.

The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ A ≤ N; 1 ≤ B ≤ N; A ≠ B), then cow A will always beat cow B.

Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.

FJ的N(1 <= N <= 100)头奶牛们最近参加了场程序设计竞赛:)。在赛场上,奶牛们按1..N依次编号。每头奶牛的编程能力不尽相同,并且没有哪两头奶牛的水平不相上下,也就是说,奶牛们的编程能力有明确的排名。 整个比赛被分成了若干轮,每一轮是两头指定编号的奶牛的对决。如果编号为A的奶牛的编程能力强于编号为B的奶牛(1 <= A <= N; 1 <= B <= N; A != B) ,那么她们的对决中,编号为A的奶牛总是能胜出。 FJ想知道奶牛们编程能力的具体排名,于是他找来了奶牛们所有 M(1 <= M <= 4,500)轮比赛的结果,希望你能根据这些信息,推断出尽可能多的奶牛的编程能力排名。比赛结果保证不会自相矛盾。

输入输出格式
输入格式:
第1行: 2个用空格隔开的整数:N 和 M

第2..M+1行: 每行为2个用空格隔开的整数A、B,描述了参加某一轮比赛的奶 牛的编号,以及结果(编号为A,即为每行的第一个数的奶牛为 胜者)

输出格式:
第1行: 输出1个整数,表示排名可以确定的奶牛的数目

  似乎格式不对?懒的改了,逃】


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const int MAXN=150;
int n,m,f[MAXN][MAXN],ans;
inline int R()
{
    int a=0;char c=getchar();
    while(c>'9'||c<'0')c=getchar();
    while(c>='0'&&c<='9')a=a*10+c-'0',c=getchar();
    return a;
}
int main()
{
    n=R();m=R();
    for(int i=1;i<=m;i++)
    {
        int aa=R(),bb=R();
        f[bb][aa]=1;
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(f[i][k]&&f[k][j]) f[i][j]=1;
    for(int i=1;i<=n;i++)
    {
        bool falg=1;
        for(int j=1;j<=n;j++)
            if(i!=j&&!f[i][j]&&!f[j][i]){falg=0;break;}
        if(falg) ans++;
    }
    printf("%d",ans);
    return 0;
}

(测评详情)

上面是显然的图论做法。这里就不细讲了。(毕竟不是今天的重点啊)


  而今天的做法是暴力循环啊。具体实现看代码吧,这次我写了注释(因为是垃圾算法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
int open[101][101];//open[i][j]意味着i胜j 
bool over[101];
int ans;
void father(int x,int y) {//找y的儿子里有没有x的爸爸 
    for(int i=1;i<=n;i++)
        if(open[y][i]>0)
            if(open[i][x]>0) {
                open[y][x]=1;
                open[x][y]=-1;
                return;
            }
    return;
}
void zailai() {
    for(int i=1;i<=n;i++) {
        bool flag=false;
        if(over[i]==true) continue;
        for(int j=1;j<=n;j++) {
            if(open[i][j]!=0) continue;
            father(i,j);//找j的儿子里有没有i的爸爸 
            father(j,i); 
        }
    }
    return;
}
void pc() {
    for(int i=1;i<=n;i++) {
        bool flag=false;
        if(over[i]==true) continue;
        for(int j=1;j<=n;j++)
            if(open[i][j]==0) {
                flag=true;
                break;
            }
        if(!flag) over[i]=true;
        if(flag==false) ans++;
        //cout<<i<<endl;
    }
    return;
}
void cl(int a,int b) {//恩,有个想法,可以把每一头牛都存成正的和负的,
    for(int i=1;i<=n;i++) {//正->胜利方 ,负->败方 
        if(open[a][i]<0){//循环胜方,如果胜方有存有胜方,那就重存;
            open[i][b]=1;
            open[b][i]=-1;
        }
        if(open[b][i]>0){//循环负方,如果负方有存胜方,那就重复
            open[a][i]=1;
            open[i][a]=-1;
        } 
    }
    open[a][b]=1;
    open[b][a]=-1;
}
int main() 
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) open[i][i]=2;
    int a,b;
    for(int i=1;i<=m;i++) {
        scanf("%d%d",&a,&b);
        cl(a,b);
    }
    pc();
    zailai();
    pc();
    cout<<ans<<endl;
    return 0;
}

浅显易懂的玄学????代码】

感觉不慢  啊

谢谢观看。希望大家跟我一样多多使用玄学方法啊

猜你喜欢

转载自www.cnblogs.com/qxyzili--24/p/10441213.html