zoukankan      html  css  js  c++  java
  • UVA

     题意:1~n这n个数,给你一个初始的顺序,再告诉你那两个数的大小关系发生了变化,求变化后的 顺序,不存在则输出IMPOSSIBLE

    思路:这题很遗憾没在比赛的时候过掉,结束后加了一行就AC了。题目真的不难,我就是根据原顺序和变化得到任意两个数之间的大小关系。然后枚举变化后的这些数对,用构造法构造一个合法的序列,最后再和原顺序进行不重复的合并。两个数组,两个指针,合并的时候未发生变化的当前数若大于变化的当前数,则输出原数,否则输出变化后的数,并将对应数组指针后移。再对得到的新顺序进行合法判断,若大小关系和要求的完全一致,则输出答案,否则无解。

    这题还有更简单的拓扑排序做法,我正在研究,稍后更新。

      1 #pragma comment(linker, "/STACK:1000000000")
      2 #include <bits/stdc++.h>
      3 #define LL long long
      4 #define INF 0x3f3f3f3f
      5 #define IN freopen("E.in","r",stdin);
      6 #define OUT freopen("out.txt", "w", stdout);
      7 using namespace std;
      8 #define MAXN 505
      9 #define MAXM 25005
     10 int s[MAXM], t[MAXM];
     11 int a[MAXN], b[MAXN], pos[MAXN], c[MAXN];
     12 bool dayu[MAXN][MAXN], res[MAXN][MAXN], u[MAXN][MAXN];
     13 bool vis[MAXN];
     14 int main()
     15 {
     16     int T;
     17     scanf("%d", &T);
     18     int cas = 1;
     19     while(T--){
     20         cas++;
     21         int n;
     22         scanf("%d", &n);
     23         for(int i = 1; i <= n; i++){
     24             scanf("%d", &a[i]);
     25         }
     26         memset(dayu, 0, sizeof(dayu));
     27         memset(vis, 0, sizeof(vis));
     28         memset(b, 0, sizeof(b));
     29         for(int i = 1; i <= n; i++){
     30             for(int j = i + 1; j <= n; j++){
     31                 dayu[a[i]][a[j]] = true;
     32             }
     33         }
     34         int m;
     35         scanf("%d", &m);
     36         memset(u, 0, sizeof(u));
     37         for(int i = 1; i <= m; i++){
     38             scanf("%d%d", &s[i], &t[i]);
     39             if(u[s[i]][t[i]]) continue;
     40             u[s[i]][t[i]] = true;
     41             dayu[s[i]][t[i]] = !dayu[s[i]][t[i]];
     42             dayu[t[i]][s[i]] = !dayu[t[i]][s[i]];
     43         }
     44         int x, y;
     45         int p = 0;
     46         bool noans = false;
     47         for(int i = 1; i <= m; i++){
     48             if(dayu[s[i]][t[i]]){
     49                 x = t[i];
     50                 y = s[i];
     51             }else{
     52                 x = s[i];
     53                 y = t[i];
     54             }
     55             if(!vis[x]){
     56                 vis[x] = true;
     57                 int j = p;
     58                 if(p == 0){
     59                     b[++p] = x;
     60                 }
     61                 else{
     62                     while(j >= 0 && dayu[x][b[j]]){
     63                         j--;
     64                     }
     65                     for(int k = p; k > j; k--){
     66                         pos[b[k]]++;
     67                         b[k + 1] = b[k];
     68                     }
     69                     b[j + 1] = x;
     70                     p++;
     71                 }
     72                 pos[x] = j + 1;
     73             }
     74             if(!vis[y]){
     75                 vis[y] = true;
     76                 int j = pos[x] - 1;
     77                 while(j >= 0 && dayu[y][b[j]]){
     78                     j--;
     79                 }
     80                 for(int k = p; k > j; k--){
     81                     pos[b[k]]++;
     82                     b[k + 1] = b[k];
     83                 }
     84                 p++;
     85                 b[j + 1] = y;
     86                 pos[y] = j + 1;
     87             }
     88         }
     89         int j = 1;
     90         memset(pos, 0, sizeof(pos));
     91         for(int i = 1; i <= n; i++){
     92             if(vis[a[i]]){
     93                 c[i] = b[j++];
     94             }
     95             else{
     96                 if(dayu[a[i]][b[j]] || j > p){
     97                     c[i] = a[i];
     98                 }
     99                 else{
    100                     c[i] = b[j++];
    101                 }
    102             }
    103             pos[c[i]] = i;
    104         }
    105         memset(res, 0, sizeof(res));
    106         for(int i = 1; i <= n; i++){
    107             for(int j = i + 1; j <= n; j++){
    108                 res[c[i]][c[j]] = true;
    109             }
    110         }
    111         for(int i = 1; i <= n; i++){
    112             for(int j = 1; j <= n; j++){
    113                 if(res[i][j] != dayu[i][j]){
    114                     noans = true;
    115                     break;
    116                 }
    117             }
    118             if(noans){
    119                 break;
    120             }
    121         }
    122         if(noans){
    123             printf("IMPOSSIBLE
    ");
    124             continue;
    125         }
    126         for(int i = 1; i < n; i++){
    127             printf("%d ", c[i]);
    128         }
    129         printf("%d
    ", c[n]);
    130     }
    131     return 0;
    132 }
  • 相关阅读:
    C++探究transform算法
    C++探究foreach算法
    C++ MFC棋牌类小游戏day6
    C++ MFC棋牌类小游戏day5
    C++ MFC棋牌类小游戏day4
    C++ MFC棋牌类小游戏day3
    MFC 字体
    C++ MFC棋牌类小游戏day2
    第三章 使用属性升级MyBank
    第二章 C#语法快速热身
  • 原文地址:https://www.cnblogs.com/macinchang/p/4740094.html
Copyright © 2011-2022 走看看