250pt:
对普通nim游戏的改编,取石子的时候只能从前往后取,每次取非空的石子,不能取者为输。
我是从后往前推的,注意当前数字如果>1,不管后面是必胜态还是必败态,肯定能调节成必胜态,如果=1,就身不由己了。。
500pt
一开始,你有n个工厂,k个专家,每工作一轮,能获得n*k的gold,购买一个工厂或者一个专家需要price的gold,你想要获得的gold是target,当你具备足够的钱买一个专家或者工厂的时候,你可以买任意多个专家或工厂。问你最小需要几轮才能获得target的gold。
这是一个 看似难写,实则更难写的模拟题。。
注意到n k肯定是越接近越好,还有当前如果要买一个专家或者工厂,那肯定是花所有的钱去买(n,k肯定是越早增大越好)。因为下一轮就赚回来了。还有就是假设当前的钱>=price了,就需要先判断一下是不是要买工厂或者专家了,因为有可能凭借当前的nk,很快就能到达target了。
代码写的比较渣,错了很多遍
#include <cstdio> #include <cstring> #include <cctype> #include <cstdlib> #include <cmath> #include <ctime> #include <iostream> #include <map> #include <set> #include <list> #include <sstream> #include <queue> #include <deque> #include <stack> #include <vector> #include <bitset> #include <algorithm> using namespace std; typedef long long lld; class StrongEconomy { public: lld ABS(lld a) { if(a > 0) return a; return -a; } void get(lld &n,lld &k,lld &tim) { if(tim >= ABS(n-k) ) { lld tn = n , tk = k; n = (tn+tk+tim) / 2; k = (tn+tk+tim+1) / 2; } else { if(n>k) k+=tim; else n+=tim; } } lld gao(lld n,lld k,lld price,lld target,lld earn) { lld tim = earn / price; earn -= tim * price; get(n,k,tim); lld tmp = mul(n,k); if(tmp == -1) return tmp; lld ans = (target - earn)/tmp; if((target-earn)%tmp) ans ++; return ans; } lld mul(lld a,lld b) { lld ans = 0; bool flag = false; for(int i=0; i<50; i++) { // cout<<ans<<endl; if(b&(1LL<<i)) { if(flag) return -1; ans = ans + a; if(ans > 1000000000000LL) return -1; } a = a + a; if(a > 1000000000000LL) flag = true; } return ans; } lld earn(lld n, lld k, lld price, lld target) { if(mul(n,k) == -1) return 1; lld round = 0; lld earn = 0; while(true) { lld tmp = mul(n,k); if(tmp == -1) return round ; // cout<<earn<<endl; if(earn >= target) break; if(earn >= price) { lld tmp = mul(n,k); lld tmp1 = (target - earn) / tmp ; if((target-earn)%tmp) tmp1++; lld tmp2 = gao(n,k,price,target,earn); // cout<<tmp1<<" "<<tmp2<<endl; if(tmp1 < tmp2 ) { round += tmp1; break; } else { lld tim = earn / price; if(tmp2 == -1) return round + 1; earn -= tim * price; // cout<<"pre"<<" "<<n<<" "<<k<<" "<<tim<<endl; get(n,k,tim); // cout<<n<<" "<<k<<" "<<earn<<endl; } } else if(price < target){ lld tmp = n * k; lld t = (price-earn)/tmp; if((price-earn)%tmp) t++; round += t; earn += t * n * k; cout<<"earn"<<" "<<earn<<endl; } else { lld tmp = n * k; lld t = (target-earn)/tmp; if((target-earn)%tmp) t++; round += t; earn += t * n * k; } // cout<<n<<" "<<k<<endl; } return round; } // BEGIN CUT HERE public: void run_test(int Case) { if ((Case == -1) || (Case == 1)) test_case_1(); } private: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } void verify_case(int Case, const lld &Expected, const lld &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } //void test_case_0() { lld Arg0 = 4294967297LL; lld Arg1 = 4294967297LL; lld Arg2 = 1000000000000LL; lld Arg3 = 100000000000LL; lld Arg4 = 1LL; verify_case(0, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); } void test_case_1() { lld Arg0 = 3LL; lld Arg1 = 2LL; lld Arg2 = 1000000000000LL; lld Arg3 = 222LL; lld Arg4 = 37LL; verify_case(1, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); } // void test_case_2() { lld Arg0 = 1LL; lld Arg1 = 1LL; lld Arg2 = 500000LL; lld Arg3 = 1000002LL; lld Arg4 = 1000001LL; verify_case(2, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); } //void test_case_3() { lld Arg0 = 5LL; lld Arg1 = 4LL; lld Arg2 = 15LL; lld Arg3 = 100LL; lld Arg4 = 5LL; verify_case(3, Arg4, earn(Arg0, Arg1, Arg2, Arg3)); } // END CUT HERE }; // BEGIN CUT HERE int main() { StrongEconomy ___test; ___test.run_test(-1); } // END CUT HERE