(intermediate)DFS UVA 11604 General Sultan

General Sultan

Input: Standard Input

Output: Standard Output

 

This is war time again! Our beloved Sultan has assumed the post of a general and going to the war with his huge army. Being an intelligent fellow as he is, he has discovered a handful of new weapons to help him win the war. In order to facilitate instructing his units, he assigns each type of weapon a single binary code. For example, he has three types of weapons -

FordCannon (code: 1)

EdmondMortar (code: 10)

HopcroftRifle (code: 00)

So, now when he makes one long beep and one short beep (that is, 10) from his grand whistle, an EdmondMortar unit is fired while when he makes two short beeps means, 00), a HopcroftRifle comes into action. Please note that, he has an unlimited supply of every types.

 

Problem arised when in an war, the units were coded like – FordCannon (01), EdmondMortar (001), HopcroftRifle (01001). Once, he went for a HopcroftRifle (01001) but his men fired a FordCannon (01) and then an EdmondMortar (001) instead. The furious Sultan realized that the coding itself was ambigous i.e. more than one sequence of the weapons can translate into the same signal.

 

Now, your task is to determine if a given coding scheme is ambiguous or not before the war starts.

 
Input

There will be around 100 test cases.  Every test case starts with a single integer N (1≤ N ≤ 100), the number of weapon types. Each of the following N lines contains a string (denoting the name of the weapon, less than 21 characters) and a binary number (the code, less than 21 characters).

 

The last test case will be followed by a single 0.

 

Output

For every test case, print “Case #x: ”, where x is the case number. Then print “Ambiguous.” if a code leads to multiple sequences or print “Not ambiguous.” otherwise.

 

Sample Input                               Output for Sample Input

3
FordCannon 1
EdmondMortar 10
HopcroftRifle 00
3
FordCannon 01
EdmondMortar 001
HopcroftRifle 01001
0
 
Case #1: Not ambiguous.
Case #2: Ambiguous.
 

 

 

题意:给出01串,问能否唯一表示,说例子好懂一些:00,01,0001 这个就有歧义,第三个武器能由前两种组合出来,所以有歧义,还有110,011,11,00 这个也有歧义因为如果是110011表示的也有两种翻译方法。

思路:我想不到正确的办法啊。。。就只能去水一下了,能水过也不错哈!平时如果没想到好办法,就想办法去水一下吧,当然不要用明显会错的方法去水啦。我的办法是,用任意两组组成一个长串,看能不能由短串组合出来,可以的话就有歧义咯,如果不可以就姑且当他可以咯。。。。

 

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 100+5;
char weapon[maxn][25];
char buffer[maxn];
int L;
bool sel[maxn];
bool vis[maxn];
int len[maxn];
int succ[maxn];
int n;
inline int cmp(const void * s1 , const void * s2)
{
 int len1 = strlen((char*)s1);
 int len2 = strlen((char*)s2);
 if (len1 < len2) return 1;
 else if (len1 > len2) return -1;
 return 0;
}

void input()
{
 for (int i = 1 ; i <= n ; ++i) scanf("%*s%s",weapon[i]);
 qsort(weapon+1,n,sizeof(weapon[0]),cmp);
 for (int i = 1 ; i <= n ; ++i)
  len[i] = strlen(weapon[i]);
 for (int i = 0 ; i <= len[1]*2 ; ++i)
 {
  int j;
  for (j = 1 ; j <= n ; ++j)
   if (len[j] <= i) break;
  succ[i] = j;
 }
}

bool match(int cur,int pos)
{
 for (int i = 0 ; i < len[cur] ; ++i)
  if (buffer[pos+i]!=weapon[cur][i]) return false;
 return true;
}

bool dfs(int pos,int s,int cur,int sel1,int sel2)
{
 if (s==3) return true;
 if (pos==L) return false;
 for (int i = cur ; i <= n ; ++i) if (match(i,pos))
 {
  if (sel1==i && !(s&1)) {
   if (!dfs(pos+len[i],s+1,succ[L-pos-len[i]],sel1,sel2))
    return false;
  }
  else if (sel2==i && !(s&2)) {
   if (!dfs(pos+len[i],s+2,succ[L-pos-len[i]],sel1,sel2))
    return false;
  }
  else if (!dfs(pos+len[i],s,succ[L-pos-len[i]],sel1,sel2))
   return false;
 }
 return true;
}

void solve()
{
 for (int i = 1 ; i <= n ; ++i)
 {
  for (int j = 1 ; j <= n ; ++j)
  {
   strcpy(buffer,weapon[i]);
   strcat(buffer,weapon[j]);
   L = len[i]+len[j];
   if (!dfs(0,0,succ[L],i,j)) {
    cout << " Ambiguous." << endl;
    return;
   }
  }
 }
 cout << " Not ambiguous." << endl;
}

int main()
{
 int Cas = 0;
 while (scanf("%d",&n),n)
 {
  ++Cas;
  input();
  printf("Case #%d:",Cas);
  solve();
 }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值