来自http://blog.youkuaiyun.com/w571523631/article/details/72862631(侵删)
总结:对于n个数,移到相同位置,往往是排序后移到中位数那里。。。。
Time Limit: 1 Sec
Memory Limit: 128 Mb
Submitted: 14
Solved: 9
Description
长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样。 今天小明起来发现自己变成了地下情报员,为了混淆视听,他需要发送一份假电报。
他有一份只有小写字母组成的长度为n × m的样本。领导要求把这个份电报发送出去。 但是小明实在是太懒了,他心想反正也只是用于混淆视听的,所以不如偷点懒。 于是他打了一行长度为n的字符串,然后复制粘贴,生成了m个这样的字符串拼在一起,把这n × m的发送出去。 为了能偷懒,也为了更加逼真,小明希望这长度为n × m的文本与之前的样本的文本距离最短。
对于两个长度均为L的字符串A和B,他们的文本距离可以表示成:
dist(A,B)=∑i=1L|A[i]−B[i]|
Input
第一行输入T,表示T组测试数据 每组数据第一行两个整数n, m(1 ≤ n × m ≤ 105) 接下来一行为样本,长度为n × m
Sample Input
2
1 6
abcdef
2 3
aabbcc
Author
csust
思路:这道题还是比较水的,意思就是分别有n个字符由一个字符移过来,距离是每个字符的差的绝对值,那么显然就是相当于各个字符串移到相同位置的最小距离和,那么就是中位数了,所以把每个位置的字符串中位数求出来就行了
ac代码:
- #include<cstdio>
- #include<iostream>
- #include<sstream>
- #include<algorithm>
- #include<cstring>
- #include<vector>
- #define LL long long
- #define INF 0x3f3f3f3f
- using namespace std;
- const int maxn = 1e5+100;
- char s[maxn];
- int n,m;
- vector<char>G[maxn];
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--)
- {scanf("%d%d",&n,&m);
- scanf("%s",s);
-
- for(int i = 0;i<n;i++)
- {
- G[i].clear();
-
- }
- for(int i = 0;i<n*m;i++)
- {
- G[i%n].push_back(s[i]);
- }
- for(int i = 0;i<n;i++)
- {
- sort(G[i].begin(),G[i].end());
- }
- int sum = 0;
- for(int i = 0;i<n*m;i++)
- {
- int len = G[i%n].size();
- sum+=abs(G[i%n][len/2]-s[i]);
-
- }
- cout<<sum<<endl;
- }
- }
Time Limit: 2 Sec
Memory Limit: 128 Mb
Submitted: 20
Solved: 15
Description
长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样。 今天小明早上6点40醒来后发现自己变成了一名高中生,这时马上就要做早操了,小明连忙爬起来 他看到操场密密麻麻的人,突然灵光一闪想到了一个很严肃的问题: 操场上有n个人,第i个人的坐标为(xi, yi),刚开始每个人都站的很松散,现在想把所有人排成一行平行x轴紧挨着的队伍,求所有人需要移动的曼哈顿距离之和的最小值。
Input
多组测试数据 每组数据第一行一个整数n(1 ≤ n ≤ 105), 表示有n个人 接下来n行每行两个整数xi, yi(−109 ≤ xi, yi ≤ 109),表示第i个人的坐标
Sample Input
3
1 1
2 1
4 1
4
1 1
1 2
2 1
2 2
思路:也是道水题很容易想到先把所有的点先聚集到同一条直线上,那么也就相当于把不同的y变成同一个y,那么就是排序后取中位数了,然后就是变成紧凑的了,还是找中位数,因为还是最短距离吗,但是这里不是变成同一个点了,而是变成紧凑的点了,那么还是很简单把中位数这个点从左边逐渐减一,右边的逐渐加一就行了
ac代码:
- #include<cstdio>
- #include<iostream>
- #include<sstream>
- #include<algorithm>
- #include<cstring>
- #include<vector>
- #define LL long long
- #define INF 0x3f3f3f3f
- using namespace std;
- const int maxn = 1e5+100;
- LL x[maxn];
- LL y[maxn];
- LL n;
- LL slovey()
- {
- LL yy = y[n/2];
- LL sum = 0;
- for(int i = 0 ;i<n;i++)
- {
- sum+=abs(yy-y[i]);
- }
- return sum;
- }
- LL slovex()
- {
- LL xx = x[n/2];
- LL tmp = x[n/2]-1;
- LL sum = 0;
- for(int i = n/2-1;i>=0;i--)
- {
- sum += abs(x[i]-tmp);
- tmp--;
- }
- tmp = x[n/2]+1;
- for(int i = n/2+1;i<n;i++)
- {
- sum+=abs(x[i]-tmp);
- tmp++;
- }
- return sum;
- }
- int main()
- {
- while(~scanf("%lld",&n))
- {
- for(int i = 0 ;i<n;i++)
- {
- scanf("%lld%lld",&x[i],&y[i]);
- }
- sort(x,x+n);
- sort(y,y+n);
- LL sum = 0;
- sum+=slovex();
- sum+=slovey();
- cout<<sum<<endl;
- }
- }