1. 程式人生 > >SRM710 div1 ReverseMancala(trick)

SRM710 div1 ReverseMancala(trick)

sin col ++ trick pac () code ios public

題目大意,

給定一個有n個點的環,n不超過10,每個點上有一個權重

起始時權重將會給出,然後有2種操作

第一種操作是,選擇一個位置i,獲得權重w = a[i],把a[i]變成0,然後接下來在環上順著走,每個數都加1,直到w為0

第二種操作是,選擇一個位置i,在換上倒著走,每個數都減去1,然後收集這個權重w,直到遇見0,然後把w填到0裏

求一種方案,使得從起始的權重到達終止的權重

不難發現,這兩種操作互為逆操作

所以只用第一種操作

先把起始權重全部集中到a[0]

終止權重也全部集中到a[0]

然後最終方案就是方案一加方案二的逆操作

orz

#include <iostream>
#include 
<cstdio> #include <vector> #include <algorithm> using namespace std; typedef vector<int> VI; VI solve(VI a){ int n = a.size(); int sum = 0; VI ans; for(auto x : a) sum += x; while(a[0] != sum){ for(int i = 1; i < n; i++){ while(a[i] != 0
){ ans.push_back(i); int p = (i+1)%n, t = a[i]; a[i] = 0; while(t){ a[p]++; t--; p = (p+1)%n; } } } } return ans; } class ReverseMancala{
public: VI findMoves(VI a, VI b){ VI x = solve(a); VI y = solve(b); VI z; int n = a.size(); reverse(y.begin(), y.end()); for(auto X : x) z.push_back(X); for(auto X : y) z.push_back(X+n); return z; } };

SRM710 div1 ReverseMancala(trick)