zoukankan      html  css  js  c++  java
  • uva10570 Meeting with Aliens

    先证明把每次i放到i位置最后次数最少:感觉,可以,用归纳法?

    //在序列后再加一个相同的序列,就可以模拟用各个数字开头的情况了
    每个位置不对的只需要换一次
    54123 ,5固定->41235变成12345

    任何一个数固定不变,都相当于从这种情况对应的1所在的位置开始排一遍12345.(例如54123 ,5固定->41235变成12345)所以只需要每个位置开始都判断变成12345所需步数即可

    把输入倒过来看,变成12345就相当于正着变成54321 (这个对称很巧妙啊),可以模块化

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    int cal(int A[], int N) {    //54123—>12345可以看做12354->12345所以每个位置开始都判断变成12345所需步数即可
        int cnt = 0, vis[505] = {0};
        for (int i = 1; i <= N; i++)  //cnt统计不用换位的个数;不用换位的A[j]就等于j,进入下一个数了
            if(!vis[i]) {            //某个数还没到正确位置
                cnt++;
                for (int j = i; !vis[j]; j = A[j])   //这个循环中一直换位直到不用换
                    vis[j] = 1;
            }
        return N - cnt;
    }
    
    int main() {
        int N, A[1010], B[1010];
        while (scanf("%d", &N), N) {
            for (int i = 1; i <= N; i++) {
                scanf("%d", &A[i]);
                B[N - i + 1] = B[2 * N - i + 1] = A[i + N] = A[i];
            }
    
            int ans = 1 << 30;
            for (int i = 0; i < N; i++)
                ans = min(ans, cal(A + i, N));
    
            for (int i = 0; i < N; i++)
                ans = min(ans, cal(B + i, N));
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
    
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N = 505;
    int p[N],k[N],w[N];
    int f[N],n;
    
    int solve(int s, int d) {
        int cnt = 0;
        for(int i = 1; i <= n; i++) {
            if(k[i] != s) {
                cnt++;
                k[w[s]] = k[i];
                w[k[i]] = w[s];
                k[i] = s;
                w[s] = i;
            }
            s += d;
            if(s > n)
                s = 1;
            if(s <= 0)
                s = n;
        }
        return cnt;
    }
    int main() {
        while(scanf("%d",&n) && n) {
            for(int i = 1; i <= n; i++) {
                scanf("%d",&p[i]);
                f[p[i]] = i;
            }
            int Min = 0x3f3f3f3f;
            for(int i = 1; i <= n; i++) {
                memcpy(k, p, sizeof(p));
                memcpy(w, f, sizeof(f));
                Min = min(Min, solve(i,-1));
                memcpy(k, p, sizeof(p));
                memcpy(w, f, sizeof(f));
                Min = min(Min, solve(i,1));
            }
            printf("%d
    ",Min);
        }
    }
  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/lqerio/p/9745599.html
Copyright © 2011-2022 走看看