PAT Advanced 1148.Werewolf - Simple Version(20)(Java)

问题描述:

1148 Werewolf - Simple Version(20 分)

Werewolf(狼人杀) is a game in which the players are partitioned into two parties: the werewolves and the human beings. Suppose that in a game,

  • player #1 said: "Player #2 is a werewolf.";
  • player #2 said: "Player #3 is a human.";
  • player #3 said: "Player #4 is a werewolf.";
  • player #4 said: "Player #5 is a human."; and
  • player #5 said: "Player #4 is a human.".

Given that there were 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liers. Can you point out the werewolves?

Now you are asked to solve a harder version of this problem: given that there were N players, with 2 werewolves among them, at least one but not all the werewolves were lying, and there were exactly 2 liers. You are supposed to point out the werewolves.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (5≤N≤100). Then N lines follow and the i-th line gives the statement of the i-th player (1≤i≤N), which is represented by the index of the player with a positive sign for a human and a negative sign for a werewolf.

Output Specification:

If a solution exists, print in a line in ascending order the indices of the two werewolves. The numbers must be separated by exactly one space with no extra spaces at the beginning or the end of the line. If there are more than one solution, you must output the smallest solution sequence -- that is, for two sequences A=a[1],...,a[M] and B=b[1],...,b[M], if there exists 0≤k<M such that a[i]=b[i] (i≤k) and a[k+1]<b[k+1], then A is said to be smaller than B. In case there is no solution, simply print No Solution.

Sample Input 1:

5
-2
+3
-4
+5
+4

Sample Output 1:

1 4

Sample Input 2:

6
+6
+3
+1
-5
-2
+4

Sample Output 2 (the solution is not unique):

1 5

Sample Input 3:

5
-2
-3
-4
-5
-1

Sample Output 3:

No Solution

作者: CHEN, Yue

单位: 浙江大学

时间限制: 400 ms

内存限制: 64 MB

代码长度限制: 16 KB

 

9月的考试好像有很多人被这题卡住了。。。其实,如果之前做过Top的Werewolf之后就会感到还是可以接受的。但是这题和Top的Werewolf相比还是有区别的,1.此题的狼人数M和说谎人数L都为2。2.此题要求以由小到大的方式输出。3.此题的时间限制比较宽松。

顺便一说,为了不和dalao们抢流量,我改用了java代码。。。

import java.util.*;
import java.io.*;
public class Main
{
	static Vector<Integer> v=new Vector<Integer>();
	static Vector<Integer> vl=new Vector<Integer>();
	static Vector<Integer> vi=new Vector<Integer>();
	static int n,w1=0,w2=0;
    public static void main(String []args) throws Exception
	{
		Main main=new Main();
		Scanner in=new Scanner(System.in);
		n=in.nextInt();
		in.nextLine();
		v.add(new Integer(0));
		vl.add(new Integer(0));
		vi.add(new Integer(0));
		for(int i=0;i<n;i++)
		{
			v.add(new Integer(in.nextInt()));
			vl.add(new Integer(0));
			vi.add(new Integer(0));
			in.nextLine();
		}
		dfs(n,0,0,n);
		if(w1==0||w2==0)
		System.out.print("No Solution");
		else
		System.out.print(w1+" "+w2);
		in.close();
    }
    public static void dfs(int sn,int ln,int wn,int un)
    {
		if(ln>2||wn>2||wn+un<2||sn+ln<2)
		return;
		else if(sn<1)
		{
			if(ln==2&&wn<=2&&wn+un>=2)
			{
				int ww1=0,ww2=0;
				if(wn==2)
				{
					for(int i=1;i<=n;i++)
					{
						if(vi.get(i)==-1)
						{
							if(ww1==0)ww1=i;
							else{ww2=i;break;}
						}
					}
					if(vl.get(ww1)*vl.get(ww2)>0)
					{ww1=0;ww2=0;}
				}
				else if(wn==1)
				{
					for(int i=1;i<=n;i++)
						if(vi.get(i)==-1){ww1=i;break;}
					if(vl.get(ww1)==-1)
					{
						for(int i=1;i<=n;i++)
							if(vi.get(i)==0&&vl.get(i)==1){ww2=i;break;}
					}
					else
					{
						for(int i=1;i<=n;i++)
							if(vi.get(i)==0&&vl.get(i)==-1){ww2=i;break;}
					}
					if(ww2==0)ww1=0;
					else if(ww2<ww1){int t=ww1;ww1=ww2;ww2=t;}
				}
				else if(wn==0)
				{
					for(int i=1;i<=n;i++)
					{
						if(vi.get(i)==0&&vl.get(i)==-1){ww1=i;break;}
					}
					for(int i=1;i<=n;i++)
					{
						if(vi.get(i)==0&&vl.get(i)==1){ww2=i;break;}
					}
					if(ww1==0||ww2==0){ww1=0;ww2=0;}
					else if(ww2<ww1){int t=ww1;ww1=ww2;ww2=t;}
				}
				if(ww1!=0&&ww2!=0)
				{
					if(w1==0||w2==0){w1=ww1;w2=ww2;}
					else if(ww1<w1){w1=ww1;w2=ww2;}
					else if(ww1==w1&&ww2<w2){w1=ww1;w2=ww2;}
				}
			}
		}
		else
		{
			int vln=vl.get(sn);
			int vn=Math.abs(v.get(sn));
			int vivn=vi.get(vn);
			if(v.get(sn)>0)
			{
				if(vi.get(vn)<0)
				{
					vl.set(sn,-1);
					dfs(sn-1,ln+1,wn,un);
				}
				else if(vi.get(vn)>0)
				{
					vl.set(sn,1);
					dfs(sn-1,ln,wn,un);
				}
				else
				{
					vl.set(sn,1);
					vi.set(vn,1);
					dfs(sn-1,ln,wn,un-1);
					vl.set(sn,-1);
					vi.set(vn,-1);
					dfs(sn-1,ln+1,wn+1,un-1);
				}
			}
			else
			{
				if(vi.get(vn)<0)
				{
					vl.set(sn,1);
					dfs(sn-1,ln,wn,un);
				}
				else if(vi.get(vn)>0)
				{
					vl.set(sn,-1);
					dfs(sn-1,ln+1,wn,un);
				}
				else
				{
					vl.set(sn,1);
					vi.set(vn,-1);
					dfs(sn-1,ln,wn+1,un-1);
					vl.set(sn,-1);
					vi.set(vn,1);
					dfs(sn-1,ln+1,wn,un-1);
				}	
			}
			vi.set(vn,vivn);
			vl.set(sn,vln);
		}		
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值