第二题其实也挺简单的,我比较喜欢做这种数据要求很有规律并且很简单的题
首先遍历以每颗树为基准,判断需要改变树高度的次数
隐含的条件就是要保证以当前树为基准时别的树高度不能小于0
取最小的那次对应基准,再判断别的树需要怎样改变
代码如下:
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#define MAXN 1010
#define INF 0x7FFFFFFF
#define ll long long
using namespace std;
int a[MAXN], sum[MAXN];
int main(void){
int n, k;
while(cin >> n >> k){
for(int i=0; i<n; ++i){
cin >> a[i];
}
for(int i=0; i<n; ++i)
sum[i] = 0;
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
int t1 = a[i]+(j-i)*k;//第j棵树期望的高度
int t2 = a[j]-t1;
if(t1 < 0){
sum[i] = INF;//以i 为基准出现负数时,应该取消当前循环
break;
}
if(t2 != 0){
sum[i]++;//以i为基准需要的改变次数
}
}
}
int flag = 0;
int min = INF;
for(int i=0; i<n; ++i){
if(sum[i] < min){
min = sum[i];
flag = i;
}
}
//以flag为基准,移动最少
cout << sum[flag] << endl;
for(int i=0; i<n; ++i){
int step = a[flag]+(i-flag)*k - a[i];
if(step > 0){
cout << "+ " << i+1 << " " << step << endl;
}
else if(step < 0){
cout << "- " << i+1 << " " << -step << endl;
}
}
}
return 0;
}
这个代码也跪了。。。又是少了一个等号。。。t1<=0时都需要退出循环
代码如下:
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#define MAXN 1010
#define INF 0x7FFFFFFF
#define ll long long
using namespace std;
int a[MAXN], sum[MAXN];
int main(void){
int n, k;
cin >> n >> k;
for(int i=0; i<n; ++i){
cin >> a[i];
}
for(int i=0; i<n; ++i)
sum[i] = 0;
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
int t1 = a[i]+(j-i)*k;//��j��������ĸ߶�
int t2 = a[j]-t1;
if(t1 <= 0){
sum[i] = INF;//��i Ϊ�����ָ���ʱ��Ӧ��ȡ��ǰѭ��
break;
}
if(t2 != 0){
sum[i]++;//��iΪ����Ҫ�ĸı����
}
}
}
int flag = 0;
int min = INF;
for(int i=0; i<n; ++i){
if(sum[i] < min){
min = sum[i];
flag = i;
}
}
//��flagΪ�����ƶ�����
cout << sum[flag] << endl;
for(int i=0; i<n; ++i){
int step = a[flag]+(i-flag)*k - a[i];
if(step > 0){
cout << "+ " << i+1 << " " << step << endl;
}
else if(step < 0){
cout << "- " << i+1 << " " << -step << endl;
}
}
return 0;
}