题目链接:http://codeforces.com/contest/402/problem/B
题意:
给一段序列代表树的高度,然而女王想要将这段序列变成等差序列。请问最少改变几棵树,如何改变。。
思路:
这题一开始思路没搞对。。。其实看一下数据范围,1000*1000,暴力也是可以搞得。暴力最开头的那个树的高度,枚举0~1000,判断当前情况需要改变几棵树。搞定。。
但是还有一种比较快的方法就是,对于每一棵已经给定树,去判断他的起始的树应该是哪一个,将出现的次数累加。最后找出出现次数最多的那个起始的树。
遍历整个序列,根据这个起始的树去判定当前的树需要改变多少。加入答案队列。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define M 10009
typedef pair<int,int> P;
int vis[M];
int s[M];
int n,k;
int main()
{
while(scanf("%d %d",&n,&k)==2)
{
for(int i = 0;i < n;i++)
{
int a;
scanf("%d",&s[i]);
a = s[i];
if(a - i*k < 1) continue;
else vis[a-i*k]++;
}
int mx = -1;
int ans = 0;
for(int i = 0;i < M;i++)
{
if(vis[i] > mx)
{
mx = vis[i];
ans = i;
}
}
queue<P> q; //记录答案
for(int i = 0;i < n;i++)
{
int a = ans+i*k - s[i];
if(a!=0)
q.push(P(i+1,a));
}
printf("%d\n",q.size());
while(!q.empty())
{
P a = q.front();
q.pop();
if(a.second < 0)
printf("- %d %d\n",a.first,-a.second);
else
printf("+ %d %d\n",a.first,a.second);
}
}
return 0;
}