1008:Hiking
题意:There are n people and i-th people will go out if the number of people going out if no less than li+1 and no larger than ri+1. You need to invite them one by one to make the number of people going out as large as possible.
思路:贪心做。。对于当前我们可以邀请的人,先邀请 r 小的,然后维护当前可以邀请的人就行了,把当前能邀请的然放进一个优先队列,每次取出 r 最小的,但是 r 得不小于当前已经参加的人数。至于怎么找当前可以邀请的人, 先把所有的[l, r]按 l 升序排列,,然后逐个添加到优先队列里就好了。所以会有两次排序,,一次按 l ,一次按 r
#pragma warning(disable:4996) #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #define N 100010 using namespace std; struct line{ int l, r, id; bool operator<(const line&op)const{ return r > op.r; } }; bool cmp(const line&a, const line&b){ if (a.l == b.l)return a.r < b.r; return a.l < b.l; } line a[N]; bool vis[N]; int ans[N]; priority_queue<line>q; int main(){ int t; scanf("%d", &t); while (t--){ int n; scanf("%d", &n); memset(vis, false, sizeof vis); memset(ans, 0, sizeof ans); while (!q.empty())q.pop(); for (int i = 1; i <= n; i++)scanf("%d", &a[i].l); for (int i = 1; i <= n; i++){ scanf("%d", &a[i].r); a[i].id = i; } sort(a + 1, a + 1 + n, cmp); int cnt = 0; int j = 1; for (int i = 0; i < n; i++){ for (; j <= n; j++){ if (a[j].l <= i){ q.push(a[j]); } else break; } if (q.empty())break; line now = q.top(); while (now.r < i){ q.pop(); if (q.empty()){ break; } now = q.top(); } if (q.empty())break; ans[i] = now.id; vis[now.id] = true; cnt++; q.pop(); } if (ans[0] == 0){ printf("0\n1"); for (int i = 2; i <= n; i++)printf(" %d", i); printf("\n"); } else{ printf("%d\n%d", cnt, ans[0]); for (int i = 1; i < cnt; i++)printf(" %d", ans[i]); for (int i = 1; i <= n; i++){ if (vis[i] == false)printf(" %d", i); } printf("\n"); } } return 0; }
1011:Key Set
题意:For a given set {1, 2, . . . , n}, you are to find the number of nonempty subsets with even sum.
思路:答案就是2^( n- 1) - 1。。至于为什么,找规律也行。规范点的方法就是考虑{2,3,4,......n}的集合。共有2^( n- 1) - 1个非空的子集,然后
对于每一个子集,若sum为偶数,就不管了,若sum为奇数就把 1 加进去,就成偶数了。O(∩_∩)O
#include <iostream> #include <cstdio> using namespace std; long long pow( long long n ) { long long ans = 1; long long base = 2; while( n ) { if( n&1 ) ans = base*ans%1000000007; base = base * base %1000000007; n>>=1; } return ans; } int main() { int t; cin >> t; while( t-- ) { long long n; scanf("%I64d", &n); long long ans = pow( n-1 ) -1; printf("%I64d\n", ans); } return 0; }