2013, VI Samara Regional Intercollegiate Programming Contest
来源:互联网 发布:软件设计师宁波分数线 编辑:程序博客网 时间:2024/06/04 19:14
题目链接
呵呵
五一不做比赛,就总结比赛了。
做完了。。。
其实就C题和I题比较有价值。。。。
那就讲讲这两个题吧
C:
给你N个数,N个区间,要求判断是否存在一个唯一的匹配。
思路: 先随便求出一个匹配 , 然后判断这个匹配是否唯一。。。
求出一个匹配的话,可以先把区间按右端点排序,维护一个set,表示当前还没有匹配的点,每次在点集中找最小的但是大于等于当前区间左端点的点跟这段区间匹配。
算是贪心吧,如果有解,肯定能找到一个解。
接下来是判断解的唯一性,解不唯一的情况如下图所示
Pnow是当前点 Snow是当前点匹配的区间,只要当这段区间的左端点到Pnow之间的所有点中存在一个点Pi,Pi所对应的区间的右端点超过了Pnow,我们就可以互换这两个点的匹配。
#include<set>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn = 100010;struct SegTree {int mx[maxn<<2];void build(int l,int r,int rt){mx[rt] = 0;if(l==r) return ;int m = l+r>>1;build(lson);build(rson);}void insert(int p,int val,int l,int r,int rt){if(val>mx[rt]) mx[rt] = val;if(l == r) return ;int m = l + r >> 1;if(p <= m) insert(p,val,lson);else insert(p,val,rson);}int query(int L,int R,int l,int r,int rt){if(L > R) return 0;if(L <= l && r <= R){return mx[rt];}int m = l + r >> 1;int ans = 0;if(L <= m) ans = max(query(L,R,lson),ans);if(R > m) ans = max(query(L,R,rson),ans);return ans;}}S;struct VAL{int num;int id;bool operator < (const VAL&cmp) const{return num < cmp.num;}}val[maxn];struct SEG{int l,r,id;bool operator < (const SEG&cmp) const {if(r != cmp.r) return r < cmp.r;return l < cmp.l;}}seg[maxn]; int mp[maxn],num[maxn];int ans[maxn];multiset<pair<int,int> > st;int main(){int n ; scanf("%d",&n);for(int i = 1; i <= n; i++){scanf("%d",&val[i].num);val[i].id = i;num[i] = val[i].num;st.insert(make_pair(num[i],i));}for(int i = 1; i <= n; i++){scanf("%d%d",&seg[i].l,&seg[i].r);seg[i].id = i;}sort(num+1,num+n+1);sort(val+1,val+1+n);sort(seg+1,seg+1+n);S.build(1,n,1);for(int i = 1; i <= n; i++){multiset<pair<int,int> >::iterator it = st.lower_bound(make_pair(seg[i].l,0));if(it==st.end() || it->first > seg[i].r ){puts("Let's search for another office.");return 0;}mp[it->second] = i;ans[seg[i].id] = it->second;st.erase(it);}for(int i = 1; i <= n; i++){S.insert(i,seg[mp[val[i].id]].r,1,n,1);}bool flag = false;for(int i = 1; i <= n; i++){int ss = mp[val[i].id];int left = seg[ss].l;int idx = lower_bound(num+1,num+n+1,left) - num;int mx = S.query(idx,i-1,1,n,1);if(mx >= val[i].num) {flag = true;break;}}if(flag){puts("Ask Shiftman for help.");}else {puts("Perfect!");for(int i = 1; i < n; i++) printf("%d ",ans[i]);printf("%d\n",ans[n]);}return 0;}
I题:
构造题:题意略去。。
首先要YY出我们应该从最后一行开始构造
仔细观察可以发现除了第一行外,每行都是同号的,那么我们可以根据上面一行的增减性,确定当前行的符号,确定了符号后我们只需要确定最后一个数是什么就好了。
最后一个数确定了,前面所有的数都确定了。确定最后一个数的时候我们肯定是用最优的方法来选取的。比如,当前行是正数,而且当前行是递增的,那么第一个数就是1,组后一个数就是下面一行所有数的和+1,
第一行的数是例外的,如果递增,我们直接令最后一个数为10^9,递减的话,令最后一个数为-10^9
中间的运算一旦超出了题目要求的范围,直接输出impossible
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef __int64 lld;int flag[2010] , n;lld ans[2010];bool solve(){ int i , j ; reverse(flag+1,flag+1+n); ans[1] = flag[2] ? 1 : -1; for(i = 3; i <= n; i++) { lld sum = 0; for(j = 1; j <= i - 2; j++) sum = sum + ans[j]; if(flag[i]) { if(flag[i-1]) ans[i-1] = sum + 1; else ans[i-1] = 1; } else { if(flag[i-1]) ans[i-1] = -1; else ans[i-1] = sum - 1; } for(j = i - 2; j >= 1; j--) { ans[j] = ans[j+1] - ans[j]; if(ans[j] > (int)1e9 || ans[j] < (int)-1e9) return false; } } ans[n] = (flag[n]?1:-1)*(int)1e9; for(j = n - 1; j >= 1; j--) { ans[j] = ans[j+1] - ans[j]; if(ans[j] > (int)1e9 || ans[j] < (int)-1e9) return false; } for(i = 1; i <= n; i++) printf("%I64d ",ans[i]); return true;}int main(){ scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&flag[i]); if(!solve()) puts("IMPOSSIBLE"); return 0;}
- 2013, VI Samara Regional Intercollegiate Programming Contest
- 第一场选拔赛 [2013, VI Samara Regional Intercollegiate Programming Contest]
- X Samara Regional Intercollegiate Programming Contest
- IX Samara Regional Intercollegiate Programming Contest K. Palindromization
- IX Samara Regional Intercollegiate Programming Contest F 三分
- 2015-2016 Samara Regional Intercollegiate Programming Contest G
- Saratov School Regional Team Programming Contest 2011
- 2013 Asia Chengdu Regional Contest
- 2013 Asia Hangzhou Regional Contest
- ACM Asia Regional (Kanpur Site) Programming Contest 2001 Problem H
- Southeastern European Regional Programming Contest 2010 D Problemsetting
- CF 2013-2014 Samara SAU ACM ICPC Quarterfinal Qualification Contest C.Victor's Research
- CF 2013-2014 Samara SAU ACM ICPC Quarterfinal Qualification Contest B. Similar Strings
- Codeforces gym 2013-2014 Samara SAU ACM ICPC Quarterfinal Qualification Contest
- Codeforces gym 2011-2012, Samara Interacademic Programming
- 2001-2002 ACM Northeastern European Regional Programming Contest-Problem G-"Library"
- The lucky numbers--Southeastern European Regional Programming Contest Bucharest, Romania 2009
- HDU/HDOJ 1551 Cable master 2001-2002 ACM Northeastern European Regional Programming Contest
- 算法:图解最小生成树之普里姆(Prim)算法
- 创建svn下的项目
- VC资源视图中显示在另一个编辑器中打开时解决办法
- Java语言中的两种异常
- 算法真谛
- 2013, VI Samara Regional Intercollegiate Programming Contest
- Design Pattern_Bridge(桥模式)
- JDK Aarrays 类中的二分查找方法
- JetBrains ReSharper 7.1.3000.2254 破解版
- Tomcat6 配置多虚拟主机,多域名绑定一IP
- QT自定义窗口插件在QT Creator的应用
- ZOJ 3305 Get Sauce(DFS+剪枝)
- define
- Heritrix eclipse安装、配置