wormhole-section1.3

来源:互联网 发布:u盘安装ubuntu系统安装 编辑:程序博客网 时间:2024/05/17 05:59

题目大意

    农夫约翰爱好在周末进行高能物理实验的结果却适得其反,导致农场上产生了N个虫洞(2<=N<=12,n是偶数),每个在农场二维地图的一个不同点。    根据他的计算,约翰知道他的虫洞将形成 N/2 连接配对。例如,如果A和B的虫洞连接成一对,进入虫洞A的任何对象体将从虫洞B出去,朝着同一个方向,而且进入虫洞B的任何对象将同样从虫洞A出去,朝着相同的方向前进。这可能发生相当令人不快的后果。    例如,假设有两个成对的虫洞A(1,1) 和 B(3,1),贝茜从(2,1)开始朝着 +x 方向(右)的位置移动。贝茜将进入虫洞 B(在(3,1)),从A出去(在(1,1)),然后再次进入B,困在一个无限循环中!| . . . .| A > B .      贝茜会穿过B,A,+ . . . .      然后再次穿过B    农夫约翰知道他的农场里每个虫洞的确切位置。虽然他不记得贝茜的当前位置,但是他知道贝茜总是向着 +x 的方向走。请帮助农夫约翰计算不同的虫洞配对(情况),使贝茜可能从不幸的位置开始被困在一个无限循环中。

输入格式

第1行:N,虫洞的数目第2到N+1行:每一行都包含两个空格分隔的整数,描述一个以(x,y)为坐标的单一的虫洞。每个坐标是在范围 0..1000000000。

输出格式

一个数字:会使贝茜从某个起始点出发沿+x方向移动卡在循环中的不同的配对。

样例输入

40 01 01 10 1

样例输出

2

题解

分为两步,第一步找出所有配对的方式,不能重复,更不能遗漏。显然不会是个全排列,因为每对的顺序无所谓,对于对之间的顺序也无所谓。本处的做法是,人为规定一个顺序,这样便不用考虑去重的问题:每对由两个元素构成,每对的第一个元素永远挑没有被挑走的第一个;每对的第二个元素依此向后挑(每对内均是小的在前大的在后,且每对与每对之间,每对的第一个元素是升序排列的)。过程如下:6个元素,分成三组,元素依此为1 2 3 4 5 6;以下是算法流程:    1 2 ,3 4 ,5 6    1 2 ,3 5 ,4 6    1 2 ,3 6 ,4 5    1 3 ,2 4 ,5 6    1 3 ,2 5 ,4 6    1 3 ,2 6 ,4 5    1 4 ,2 3 ,5 6    1 4 ,2 5 ,3 6    1 4 ,2 6 ,3 5    。    。    。第二个问题是对于每种配对方式,怎样判断牛进入了无限循环:用step表示牛经过的虫洞个数,由于牛永远向一个方向走,所以牛走的路径是唯一的,如果牛第二次进入(不是经过,因为经过可能是离开)同一个虫洞,那么一定会陷入循环,所以当step>2*N的时候,一定陷入循环。

代码

#include<stdio.h>int N,count=0,flag=0;long int a[15][2];int b[15][2];int g(int step,int i){int number,j,s;number=b[i][1];if(step>2*N){flag=1;return 0;}else{for(j=0;j<N;j++){    if(number==b[j][1]&&j!=i)    {   s=j;break;}}for(j=0;j<N;j++){    if(a[j][1]==a[s][1]&&a[j][0]>a[s][0])    {        g(step+1,j);        break;    }}}return 0;}int f(int k){    int i,j;if(k==0){    for(i=0;i<N;i++)    {        flag=0;        g(0,i);        if(flag==1)            break;    }    if(flag==1)        count++;}else{    for(j=0;j<N;j++)    {        if(b[j][1]==0)        {            b[j][1]=k/2;            break;        }    }    for(i=0;i<N;i++)    {        if(b[i][1]!=0)            continue;        else        {            b[i][1]=k/2;            f(k-2);            b[i][1]=0;        }    }    b[j][1]=0;}return 0;}int main(){       scanf("%d",&N);int i,j,temp;for(i=0;i<N;i++){    b[i][0]=i;    b[i][1]=0;}//  b[0][1]=1;b[1][1]=1;for(i=0;i<N;i++)    scanf("%d %d",&a[i][0],&a[i][1]);for(i=0;i<N;i++)    for(j=0;j<N-1-i;j++)    {        if(a[j][1]>a[j+1][1])        {            temp=a[j][1];            a[j][1]=a[j+1][1];            a[j+1][1]=temp;            temp=a[j][0];            a[j][0]=a[j+1][0];            a[j+1][0]=temp;        }    }for(i=0;i<N;i++)    for(j=0;j<N-1-i;j++)    {        if(a[j][1]==a[j+1][1])        if(a[j][0]>a[j+1][0])        {            temp=a[j][1];            a[j][1]=a[j+1][1];            a[j+1][1]=temp;            temp=a[j][0];            a[j][0]=a[j+1][0];            a[j+1][0]=temp;        }    }    f(N);//  g(0,1);    printf("%d\n",count);    for(i=0;i<N;i++)        printf("%d %d\n",a[i][0],a[i][1]);    return 0;}
原创粉丝点击