UVa 11330 (置换 循环的分解) Andy's Shoes

和UVa11077的分析很类似。

我们固定左脚的鞋子不动,然后将右脚的鞋子看做一个置换分解。

对于一个长度为l的循环节,要交换到正确位置至少要交换l-1次。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <map>
 4 using namespace std;
 5
 6 bool vis[10000 + 10];
 7
 8 int main()
 9 {
10     //freopen("in.txt", "r", stdin);
11
12     int T;
13     scanf("%d", &T);
14     while(T--)
15     {
16         int n, a, b;
17         map<int, int> m;
18         scanf("%d", &n);
19         for(int i = 0; i < n; i++)
20         {
21             scanf("%d%d", &a, &b);
22             m[a] = b;
23         }
24         int ans = 0;
25         map<int, int>::iterator It;
26         memset(vis, false, sizeof(vis));
27         for(It = m.begin(); It != m.end(); It++)
28         {
29             int i = It->first;
30             if(!vis[i])
31             {
32                 int cnt = 0;
33                 int j = i;
34                 do
35                 {
36                     cnt++;
37                     vis[j] = true;
38                     j = m[j];
39                 }while(j != i);
40                 ans += cnt - 1;
41             }
42         }
43         printf("%d\n", ans);
44     }
45
46     return 0;
47 }

代码君

UVa 11330 (置换 循环的分解) Andy's Shoes

时间: 2024-12-25 04:55:02

UVa 11330 (置换 循环的分解) Andy's Shoes的相关文章

LA 3641 (置换 循环的分解) Leonardo&#39;s Notebook

给出一个26个大写字母的置换B,是否存在A2 = B 每个置换可以看做若干个循环的乘积.我们可以把这些循环看成中UVa 10294的项链, 循环中的数就相当于项链中的珠子. A2就相当于将项链旋转了两个珠子间的距离,珠子0.2.4...构成一个循环,一共有gcd(n, 2)个循环,每个循环的长度为n / gcd(n, 2) 所以当一个循环的长度为奇数的时候,平方以后还是原来的长度: 当一个循环的长度为偶数的时候,平方以后就会分解为两个长度都等于原来循环长度一半的循环. 先将置换B分解循环,对于其

UVA 11330 - Andy&#39;s Shoes(置换分解)

UVA 11330 - Andy's Shoes 题目链接 题意:andy有很多双鞋子,每双鞋子有一个编号,现在他把鞋子左右左右放回去,可是不能保证所有鞋子左边和右边是同一编号,现在要求用最少的交换次数,使得所有鞋子左右编号相同 思路:置换的分解,固定左边的鞋子,这样右边的鞋子就可以看成是放在哪个位置,然后根据这个求出每个循环的长度,最后每个循环长度-1的总和就是答案 代码: #include <cstdio> #include <cstring> int t, n, vis[10

uva 11330 - Andy&#39;s Shoes(置换)

题目链接:uva 11330 - Andy's Shoes 题目大意:小andy有很多鞋,穿完到处丢,后来他把所有鞋都放回鞋架排成一排,保证了鞋的左右交替,但是颜色混了.问说他至少移动多少次可以将鞋分类好. 解题思路:对应奇数位置为左鞋,偶数位置为右鞋,一双鞋只有一只左鞋和一只右鞋,保证不换左变鞋子,以左鞋的位置为基准换右边鞋子,对应右边鞋子的位置即为一个置换,将置换的循环分解为x个互不相干的循环,ans=n-x #include <cstdio> #include <cstring&g

UVa 11330 - Andy&#39;s Shoes

题目:有双配对出错鞋子,要求最少的交换次数,使得鞋子配对摆放. 分析:组合数学,置换群.统计置换中循环的个数k,则结果为n-k. 循环内部(设有m个元素)需要交换m-1次(除最后一次,每次交换最多只能有一个复位) 说明:注意鞋子的编号不一定是1~n,是1~10000之间的数字,计算时需要做映射. #include <cstdlib> #include <cstdio> int value[10011]; int Lshoes[10011]; int Rshoes[10011]; i

uva 11077 置换

1 /** 2 给定一个置换,看能不能存在一个置换A^2 = B 3 思路; 循环节长度为偶数n的置换只能由循环节长度为长度2*n 的置换A*A 而变得.所以只需求出循环节,看循环节长度为偶数的个数是否为偶数个即可.. 4 训练指南 5 **/ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 using namespace std; 10 const int maxn = 30; 11 1

LA 3510 (置换 循环分解) Pixel Shuffle

思路挺简单的,题目中的每个命令(包括命令的逆)相当于一个置换. 用O(n2k)的时间复杂度从右往左求出这些置换的乘积A,然后求m使Am = I(I为全等置换) 还是先把A分解循环,m则等于所有循环节长度的最小公倍数. 需要注意的是: 执行命令是从右往左执行的,这是题目中说的=_= 其他命令还好,mix那个命令把我搞得晕头转向,题中给的是反的,我们要反过来求原图像(i, j)在新图像中的位置. 1 #include <cstdio> 2 #include <cstring> 3 #i

Uva 12299 带循环移动的RMQ(线段树)

题目链接:https://vjudge.net/contest/147973#problem/C 题意:传统的RMQ是一个不变的数组a求区间最值.现在要循环移动(往前移动). 分析:求区间问题,很容易想到线段树,西东就相当于单点更新. 建树,有两种方案,第一种是nlogn,就是不断的更新,更新logn,有n个数. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 6 const int INF = 1000000000; 7 con

Uva 11134 Fabled Rooks (问题分解 + 贪心放置)

题意: 给你n*n的棋盘,让放置n个车 使他们之间并不能相互攻击 附加条件是 给定n个车的放置区间 用左上角和右下角的坐标来表示 解题思路: 首先明确 横向的约束和纵向的约束其实并不互相影响 所以可以对横向和纵向单独求解 把问题变成两个一维的区间选点问题来求解 另外 在取点的时候 有贪心的思路在里面 对于n个区间 应该先选择区间中r最小的区间进行放置可放置的点 可以简单认为这是因为r越小的区间 其选择的灵活性就越低. 我刚开始的时候 是采取了先放置区间长度小的 在放置l小的区间 不正确. cod

UVa 110 没有循环的排序程序

题意:构造Pascal的排序程序.初看是写Pascal程序,不了解的以为会很难,但其实程序的大部分是固定的,直接printf就可以,主要在于写比较的if-else部分. 思路:看sample out可以大概知道程序的构成,其他部分直接输出,主要写比较的部分.比较的时候,可以看成两个集合,A是已排好序的,S是全集,cur是从左到右扫描S的当前位置.用递归写的,前半部分是当当前位置cur到达n时,即可以输出了:剩下的是如何填写当前位置cur以及维持A是已排好序的这个性质.将新元素S[cur]从A的最