您的位置:首页 > 其它

反向操作

2015-03-16 22:33 204 查看
第一次写博客诶,好高兴!!!

反向操作

题目大意:

在一个首尾相接的正整数数列中,做一次操作的意思是说将每个数变成这

个数和相邻两个数的和,现在给出操作后的数列,请求出初始时的序列。

输入:

第一行一个数N表示序列的长度

下面N行每行一个数表示这个操作后的序列

输出:

输出N行每行一个数,表示操作前的序列

样例输入:

3

5

5

5

样例输出:

2

1

2

(当然也有其他的解,请读者自己判断。。。)

数据范围

N<=10000,输入中的所有数都满足<=109

看到这个题,突然发现好像可以写暴力啊!!!!!

然后看看数据范围。。。。。。

其实这个题是一个数列题(对OIER来说应该没有问题)

应分三种情况考虑,一个是N%3 == 0时,一个是N%3 == 1时,一个是N%3 == 2时



反正只要求出一组解,我们就可以用特殊的XX技巧

(a[i]为ans[i-1]+ans[i]+ans[i+1]的和,ans为要输出的答案)

首先,在N%3 == 1时,我们可以把1~N的编号分为{{1},{2~4},{5~7},……

{N-2~N}},然后可以把分好的这个序列分为1和其他数,因为N%3 == 1,所以就可

以理所当然可以算出其他数ans[2]到ans
的和,然后我们可以设sum为sum=(a

[1]+a[2]……+a
)/3,这就是p=ans[1]+ans[2]……+ans
的值,然后我

们将p-sum就求出了a[1]的值。然后我们用类似的方法可以求出a[2],得到a[1]和

a[2]的值,就可以求出数列的值。

在N%3 == 2的时候与N%3 == 1的时候类似。

最复杂的莫过于N%3 == 0的时候了。这样也可以先假设ans[1]=0,然后可以一次

求出ans[4],ans[7]……ans[3i+1]的所有值。假如求出的值出现了负数,找出

最小值Min,把每个数加上Min+1,以此保证每个数都大于0。然后也可以用类似的

方法可以设ans[2]=0求出ans[5],ans[8]……ans[3i+2],然后和3i+1的情况一

样,去处理。最后得出a[3i+1]与a[3i+2]自然可以得出a[3i]。

好吧,这个题这样就做完了。

下面放上代码

#include <cstdio>
#include <algorithm>
#define MAXN 10005
using namespace std;
long long ans[MAXN] = {0}, a[MAXN] = {0};
long long sum = 0;
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
scanf("%I64d", &a[i]);
sum = sum + a[i];
}
sum = sum / 3;
if (n == 1)
ans[1] = 1;
else
if (n == 2)
ans[1] = 1, ans[2] = a[1] - 1;
else
if (n == 3)
ans[1] = 1, ans[2] = 1, ans[3] = a[1] - 2;
else
if (n % 3 == 1)
{
long long ss = 0;
for(int i = 2;i <= n; i = i + 3)
ss = ss + a[i];
ans
= sum - ss;
ss=0;
for (int i = 3;i <= n; i = i + 3)
ss = ss + a[i];
ans[1] = sum - ss;
ans[2] = a[1] - ans
- ans[1];
for (int i = 3; i < n; ++i)
ans[i] = a[i - 1] - ans[i - 1] - ans[i - 2];
}
else
if (n % 3 == 2)
{
long long ss = 0;
for(int i = 2;i <= n; i = i + 3)
ss = ss + a[i];
ans[1] = ss - sum;
ss = 0;
for (int i = 1; i < n; i = i + 3)
ss = ss + a[i];
ans
= ss - sum;
ans[2] = a[1] - ans
- ans[1];
for (int i = 3; i < n; ++i)
ans[i] = a[i - 1] - ans[i - 1] - ans[i - 2];
}
else
{
long long Min = 0;
for (int i = 4; i <= n; i = i + 3)
{
ans[i] = ans[i - 3] + a[i - 1] - a[i - 2];
Min = min(Min, ans[i]);
}
for (int i = 1; i <= n; i = i + 3)
ans[i] = ans[i] - Min + 1;
Min = 0;
for (int i = 5; i <= n; i = i + 3)
{
ans[i] = ans[i - 3] + a[i - 1] - a[i - 2];
Min = min(Min, ans[i]);
}
for (int i = 2; i <= n; i = i + 3)
ans[i] = ans[i] - Min + 1;
for (int i = 3; i <= n; i = i + 3)
ans[i] = a[i - 1] - ans[i - 1] - ans[i - 2];
}
for (int i = 1; i <= n; ++i)
printf("%I64d\n" ,ans[i]);
return 0;
}


谢谢大家!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数列
相关文章推荐