[CF805C] Find Amir(贪心,构造,模拟)
题目链接:http://codeforces.com/contest/805/problem/C
题意:n个数,从i到j的花费为(i+j)%(n+1),问n个数都要走一遍,求最小花费。
希望尽可能地让i+j是n+1的倍数,所以构造:从1开始,那么下一个点必为n,因为(1+n)%(1+n)=0为最小花费,从n则可以到2,没办法,只能花费1。以此类推反复横跳。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100100; 5 int n, a[maxn]; 6 bool vis[maxn]; 7 8 int main() { 9 // freopen("in", "r", stdin); 10 while(~scanf("%d", &n)) { 11 memset(vis, 0, sizeof(vis)); 12 int mod = n + 1; 13 int ret = 0, cnt = 1; 14 int cur = 1; 15 int lo = 2; 16 vis[cur] = 1; 17 while(cnt <= n) { 18 if(!vis[mod-cur]) { 19 vis[mod-cur] = 1; 20 cur = mod - cur; 21 } 22 else { 23 vis[lo] = 1; 24 cur = lo; 25 lo++; 26 ret++; 27 } 28 cnt++; 29 } 30 printf("%d\n", ret-1); 31 } 32 return 0; 33 }
???找规律发现,这答案直接输出(n-1)/2就行了。。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100100; 5 int n, a[maxn]; 6 bool vis[maxn]; 7 8 int main() { 9 // freopen("in", "r", stdin); 10 while(~scanf("%d", &n)) { 11 printf("%d\n", (n-1)/2); 12 } 13 return 0; 14 }