URAL 1670 Asterisk(暴力DFS)

 

 

题目大意

 

定义一个对于数列的运算符:*,数列 A*B 表示将数列 A 放在数列 B 的后面,组成一个新的数列,例如:

  A=(1, 2, 3, 4)

  B=(7, 8, 9, 10)

  A*B=(7, 8, 9, 10, 1, 2, 3, 4)

现在给你一个 1~n(1n10000) 的排列,要求通过给 1 2 3 4 5 ... n 添加括号、逗号和 ‘*’ 号使得表达式最终运算的结果是给出的排列,例如

  3 4 2 1 可以通过 (1)*(2)*(3, 4) 这个数列表达式得到

如果不能得到当前的排列,输出 imposible

 

做法分析

 

暴力DFS,考虑将当前的数列分成两个部分 A 和 B,这个数列要么是 ‘B*A’ 得到的,要么是 ‘A,B’ 得到的

 

A 必然是一个连续的自然数的排列,同样的 B 也是另一个连续的自然数的排列,同时 A 和 B 非空

  (1). 如果 A 含有当前数列中的最小值,那么,B 肯定含有当前数列中的最大值,当前数列由 'A,B' 得到

  (2). 如果 A 含有当前数列中的最大值,那么,B 肯定含有当前数列中的最小值,当前数列由 ‘A*B’ 得到

如果不能分解成上面两种情况,那么,当前的数列肯定无解

 

然后直接暴力 DFS 即可,当时抱着 T 的心态去搞的,没想到竟然过了,这个复杂度还真不好算

 

参考代码

 

URAL 1670 Asterisk(暴力DFS)
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 

 5 using namespace std;

 6 

 7 const int N=10005, INF=0x3fffffff;

 8 

 9 char ans[1000*N];

10 int A[N], n, pos, B[N];

11 

12 void fillinto(int x) {

13     if(x==0) {

14         ans[pos++]='0'+x;

15         return;

16     }

17     B[0]=0;

18     while(x) {

19         B[++B[0]]=x%10;

20         x/=10;

21     }

22     for(int i=B[0]; i>0; i--) ans[pos++]=B[i]+'0';

23 }

24 

25 bool DFS(int L, int R, int Min, int Max) {

26     if(L==R) {

27         fillinto(A[L]);

28         return true;

29     }

30     int curMin=INF, curMax=-INF;

31     for(int i=L; i<R; i++) {

32         curMax=max(curMax, A[i]);

33         curMin=min(curMin, A[i]);

34         if(curMax-curMin!=i-L) continue;

35         if(curMax==Max) {

36             ans[pos++]='(';

37             if(!DFS(i+1, R, Min, curMin-1)) return false;

38             ans[pos++]=')', ans[pos++]='*', ans[pos++]='(';

39             bool cur=DFS(L, i, curMin, curMax);

40             ans[pos++]=')';

41             return cur;

42         }

43         else if(curMin==Min) {

44             if(!DFS(L, i, curMin, curMax)) return false;

45             ans[pos++]=',';

46             return DFS(i+1, R, curMax+1, Max);

47         }

48     }

49     return false;

50 }

51 

52 int main() {

53     while(scanf("%d", &n)!=EOF) {

54         for(int i=1; i<=n; i++) scanf("%d", &A[i]);

55         pos=0;

56         ans[pos++]='(';

57         bool cur=DFS(1, n, 1, n);

58         ans[pos++]=')';

59         ans[pos++]=0;

60         if(!cur) printf("IMPOSSIBLE\n");

61         else printf("%s\n", ans);

62     }

63     return 0;

64 }
Asterisk

 

题目链接 & AC 通道

 

URAL 1670 Asterisk

 

 

 

你可能感兴趣的:(DFS)