Mathematics
jzoj 1747
題目大意
有n堆石子,總和爲,現在對於兩堆石子,你可以從a中取b的分量到b(a要大於b),問合成一堆大小爲的石子要怎麼做(輸出a,b)
輸入樣例
2 2
3 1
輸出樣例
2 1
1 2
數據範圍
對於30%的數據,n=2;
對於100%的數據,
解題思路
既然總和就是最後一堆的大小那就是把所有合在一起啦
我們從小到大枚舉二進制下的每一位,如果有1的那就找另一個有1的和他調一下,這樣就可以清掉一位,我們不停清,最後就只剩了
代碼
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n, k, p, s, a[100500];
int main()
{
scanf("%lld %lld", &n, &k);
for (ll i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
for (ll sum = 1, i = 0; i < k; ++i, sum <<= 1)//每一位
for (ll j = 1; j <= n; ++j)
if (a[j]&sum)
{
if (!p)//沒有前面一個先記錄下來
s = j, p = 1;
else
{
if (a[j] > a[s])//有前面一個就要判斷誰給誰
{
a[j] -= a[s];//給他那麼多就減掉那麼多
a[s] <<= 1;//乘上2
printf("%lld %lld\n", s, j);
}
else
{
a[s] -=a[j];
a[j] <<= 1;
printf("%lld %lld\n", j, s);
}
p = 0;
}
}
return 0;
}