传送门:Round 177 div2
B .Polo the Penguin and Matrix 二分问题
题目的描述是:给你一个n*m的矩阵,和一个常数k,每次可以对矩阵中的任意一个元素进行一次 加k或减k的运算,问最少的运算次数使得矩阵中的每个元素值都相等。
突然发现这道题好像假期训练做的伐木的题,队长是用的二分算法,羽哥用的是动态规划,(原题目只是求加,木有求减)数据比较大,用暴力绝对会超时,应该才用二分算法。
算法:(1)先对所有的输入数据进行从大到小的排序,然后从a[2]开始直到a[n]每项减去a[1],然后只剩下k的倍数,如果其中一项不能被k整除,输出-1,无法达到结论。
(2)这是a[1]=0;然后从1-n进行二分,每次去中间项,和全局变量Min进行比较,得出结论。本二分是左右两边同时进行,和二分查找(一边进行)不同。
postcode:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int Min,len;
int a[20000];
void BSearch(int left,int right){
if(left>right)return ;
int sum=0;
int middle=(left+right)/2;
int num=a[middle];
for(int i=1;i<=len;i++)
sum+=abs(num-a[i]);
if(Min>sum)Min=sum;
BSearch(left,middle-1); //左边二分
BSearch(middle+1,right); //右边二分
}
int main()
{
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
Min=99999999;
int i,flag=1;;
len=n*m;
for(i=1;i<=len;i++)
scanf("%d",&a[i]);
sort(a+1,a+len+1);
for(i=2;i<=len;i++){
a[i]-=a[1];
if(a[i]%k!=0){flag=0;break;}
else a[i]=a[i]/k;
}
a[1]=0;
if(flag==0){printf("-1\n");continue;}
BSearch(1,len);
printf("%d\n",Min);
}
return 0;
}
C. Polo the Penguin and Strings
题意:
输入n,k, n代表的是字符串的长度,k代表字符传中字母的个数
注意字符串中s[i]!=s [i+1] (1<=i<n)
然后输出满足条件的最小字典序
解析
ab这个字符时最小的,不断循环就好了,但要记住还要满足字母的个数要相等,ab循环只有两个字母,若要求有四个字母,还有加上c,d;
注意一些不能取值的特殊情况,n<k是不成立的 还有就是 k=1 n>k时也是不成立的,还有n=1,k=1输出a的情况
下面见代码:
链接: 代码链接