2015年ACM长春网络赛(准备做掉7道:已经更新到6道)
总结汇总:模板
int getmax_min(char s[]) {//字符串的最大表示法:返回最小数组下标 , j = , k = ; while(i < len && j < len) { k = ; while(s[i+k] == s[j+k] && k < len) k++; if(k == len) return min(i,j); if (s[i + k] < s[j + k]) > j) i = i + k + ; else i = j + ; > i) j = j + k + ; else j = i + ; } return min(i, j); }
A题。水题。优先队列。纯模拟。
WA了很久很久的经验教训就是 好好审题 好好写题 把数据范围套串了 简直了
有几个要 注意的wa点
1.不同数据各自的数据范围别看错了
2.审题,最后的最后,是要把所有的朋友都放进来的
3.若两个人同时满足进入条件的时候,价值高的先进,价值相同的,先来的先进。
4.还有还有!!!!队列啊栈啊这种数据结构一定要注意 判空!判空!!!
#include <cstdio> #include <queue> #include <algorithm> using namespace std; + ; int ans[maxn]; struct ss { int val,id; ]; bool operator < (const ss& other)const { if(val != other.val) return val < other.val; return id > other.id; } }stu[maxn]; struct sss { int t,p; bool operator < (const sss& other)const { return t < other.t; } }door[maxn]; int main() { int T,k,m,q; scanf("%d",&T); while(T--) { priority_queue<ss>que; scanf("%d%d%d",&k,&m,&q); ; i <= k; i++) { scanf("%s %d", stu[i].name, &stu[i].val); stu[i].id = i; } ; i < m; i++) { scanf("%d%d", &door[i].t, &door[i].p); } sort(door, door + m); , outid = ; ; i < m; i++) { while(stu[cnt].id <= door[i].t && cnt <=k) { que.push(stu[cnt]); cnt++; } while((door[i].p--) && (!que.empty())) { ss temp = que.top(); que.pop(); ans[ outid ] = temp.id; outid ++; } } while(cnt <= k) que.push(stu[cnt++]); while(!que.empty()) { ss temp = que.top(); que.pop();ans[ outid ] = temp.id; outid ++; } int x; ; i < q; i++) { scanf("%d",&x); printf()?'\n':' '); } } ; }
题目大意应该是不断的把 连接的池塘少于两个的 池塘移除。最后各个连通分量中,拥有奇数个池塘的价值总和。
怎么解决这个问题呢。相当于移除所有度数小于2的顶点。是用一个类似于。拓扑排序的思路。
d数组:用来记录顶点的度数。vis数组:来标记是否应该被移除。
void toposort() { queue<int>que; ;i<=n;i++) ) { vis[i] = ; que.push(i); } while(!que.empty()) { int t = que.front();que.pop(); ;i<G[t].size();i++) { int v = G[t][i]; ) { d[v]--; ) { vis[v] = ; que.push(v); } } } } }
那如何统计。各个连通分量中的顶点个数呢,用dfs。搜索。
另外就是注意!sum的类型应该是LL的。高亮部分叠加的时候,要注意val数组是int型的。
#include <cstdio> #include <queue> #include <vector> #include <cstring> using namespace std; typedef long long LL; + ; int n,m,T,x,y,d[maxn],vis[maxn],val[maxn]; LL sum,amount; vector<int>G[maxn]; void toposort() { queue<int>que; ;i<=n;i++) ) { vis[i] = ; que.push(i); } while(!que.empty()) { int t = que.front();que.pop(); ;i<G[t].size();i++) { int v = G[t][i]; ) { d[v]--; ) { vis[v] = ; que.push(v); } } } } } void dfs(int s) { vis[s] = ; ;i<G[s].size();i++) { int v = G[s][i]; ) { amount++; sum = sum + (LL)val[v]; dfs(v); } } } int main() { scanf("%d",&T); while(T--) { memset(d,,sizeof(d)); memset(vis,,sizeof(vis)); ;i<=maxn;i++) G[i].clear(); scanf("%d%d",&n,&m); ;i<=n;i++) scanf("%d",&val[i]); ;i<m;i++) { scanf("%d%d",&x,&y); G[x].push_back(y); G[y].push_back(x); d[x]++, d[y]++; } toposort(); LL tot = ; ;i<=n;i++) { ) {//说明未被删除 sum = val[i]; amount = ; dfs(i); == ) tot = tot + sum; } } printf("%lld\n",tot); } }
注意一下题意就好了,它不是让你求最短路,是每段小于那个给出的值就可以了。
在这张图上,权值小于等于给定值的路,相关的顶点有一个c(n,2)的组合。也就是n*(n-1)/2
在并查集里加一个数组记录一下这个并查集里面的结点的总数就行了。
哦对了,这里最关键的是,利用离线处理,而不是在线处理来提高效率。
#include <cstdio> #include <map> #include <set> #include <queue> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; #define mem0(x) memset(x,0,sizeof(x)) #define mem1(x) memset(x,-1,sizeof(x)) + ; struct QQ { int w,id; bool operator <(const QQ& other) { return w < other.w; } }Q[+]; + ]; struct edge { int x,y,w; bool operator <(const edge& other) { return w < other.w; } }es[ + ]; int pa[maxn], num[maxn]; void init(int n) { ;i<=n;i++) pa[i] = i, num[i] = ; } int uf_find(int x){return x == pa[x] ? x : (pa[x] = uf_find(pa[x]));} void join(int x,int y) { int fx = uf_find(x);int fy = uf_find(y); if(fx != fy) pa[fx] = fy, num[fy] += num[fx]; } int main() { int T,n,m,q; scanf("%d",&T); while(T--) { scanf("%d%d%d", &n, &m, &q); init(n); ;i<m;i++) { scanf("%d%d%d", &es[i].x, &es[i].y, &es[i].w); } sort(es, es + m); ;i<q;i++) { scanf("%d",&Q[i].w); Q[i].id = i; } sort(Q, Q + q); , j = ; ;i<q;i++) { while(j < m && es[j].w <= Q[i].w) { int fx = uf_find(es[j].x); int fy = uf_find(es[j].y); j++; if(fx == fy) continue; cnt += (num[fx] + num[fy]) * (num[fx] + num[fy] - ) -num[fx] * (num[fx] - ) -num[fy] * (num[fy] - ); join(fx,fy); } ans[ Q[i].id ] = cnt; } ; i < q; i++) { printf("%d\n",ans[i]); } } ; }
这道题。字符串的最大表示法。
getmax_min函数是最大表示中取最小的数组下标,_max就是取最大的数组下标。
要有一步,预处理:
; i < len; i++) { ss[*len-i-] = ss[len-i-] = s[i+len] = s[i]; } ss[*len] = *len] = '\0';//容易遗漏
然后把,表示出来的两个字符串放到两个新的数组中保存。
; i < len; i++) { s_0[i] = s[ans_0+i]; s_1[i] = ss[ans_1+i]; } s_0[len] = s_1[len] = '\0';
接下来就是根据题意进行一些列判定和输出就行了。
主干代码在两个函数上。
需要注意的地方,都有高亮了。
第二个函数中k == len之后的处理,很关键,是哪来找循环节的,不然算法会退化到n²。
其他的怎么理解,昂,只能自己画图吧,画着画着就懂了吧。。。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; + ; *maxn], ss[*maxn], s_0[maxn], s_1[maxn]; int T,len; int getmax_min(char s[]) { , j = , k = ; while(i < len && j < len) { k = ; while(s[i+k] == s[j+k] && k < len) k++; if(k == len) return min(i,j); if (s[i + k] < s[j + k]) > j) i = i + k + ; else i = j + ; > i) j = j + k + ; else j = i + ; } return min(i, j); } int getmax_max(char s[]) { , j = , k= ; while(i < len && j < len) { k = ; while(s[i + k] == s[j + k] && k < len) k++; if (k == len) { int loop = abs(i - j); return len - loop + i; } else { if (s[i + k] < s[j + k]) > j) i = i + k + ; else i = j + ; > i) j = j + k + ; else j = i + ; } } if(j >= len) return i; return j; } int main() { scanf("%d",&T); while(T--) { scanf("%d",&len); scanf("%s",s); ; i < len; i++) { ss[*len-i-] = ss[len-i-] = s[i+len] = s[i]; } ss[*len] = *len] = '\0'; int ans_0 = getmax_min(s); int ans_1 = getmax_max(ss); ; i < len; i++) { s_0[i] = s[ans_0+i]; s_1[i] = ss[ans_1+i]; } s_0[len] = s_1[len] = '\0'; int p = strcmp(s_0, s_1); ) { printf(); } ) { printf("%d 1\n", len - ans_1); } else { < len - ans_1) { printf(); } else { printf("%d 1\n", len - ans_1); } } } ; }
裸的线段树(建树+区间和查询)。。。。没啥说的,模板题。
#include <cstdio> #include <map> #include <set> #include <queue> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; #define mem0(x) memset(x,0,sizeof(x)) #define mem1(x) memset(x,-1,sizeof(x)) #define lson l, m, rt << 1 #define rson m+1, r, rt << 1 | 1 ; ]; ], MAX[rt << | ]);} void build(int l,int r,int rt) { if(l == r) {scanf("%d",&MAX[rt]);return ;} ; build(lson), build(rson); pushup(rt); } int query(int ll,int rr,int l,int r,int rt) { if(ll <= l && rr >= r) return MAX[rt]; ; ; if(ll <= m ) ans = max(ans, query(ll,rr,lson)); if(rr > m) ans = max(ans, query(ll,rr,rson)); return ans; } int main() { int t, x, y, m, n; scanf("%d",&t); while(t--) { scanf("%d",&n); build(,n,); scanf("%d",&m); ;i<m;i++) { scanf("%d%d",&x,&y); ,n,); printf("%d\n",ans); } } ; }
!!!其实就是个,给树的中序遍历和前序遍历的结果,构造个树。。然后dfs一下就好了。如果看出来是 中序+前序 这题就变得非常水了。
#include <cstdio> ],]; struct A { int left,right; }node[]; int build(int l1,int r1,int l2,int r2) { ; int root = pre[l2]; int p = l1; while(in[p] != root) p++; int cnt = p - l1; node[root].left = build(l1, l1+cnt-,l2+,l2+cnt); node[root].right = build(l1+cnt+,r1,l2+cnt+,r2); return root; } void dfs(int x,int root) { ) { printf("E"),dfs(x,node[root].left); } ) printf("W"),dfs(x,node[root].right); else return ; } int main() { int T,n,m; scanf("%d", &T); while(T--) { scanf("%d",&n); ; i <= n; i++) scanf("%d",&pre[i]),in[i] = i; ,n,,n); scanf("%d",&m); ; i < m; i++) { int x; scanf("%d",&x); dfs(x,root); puts(""); } } ; }
2015年ACM长春网络赛(准备做掉7道:已经更新到6道)的更多相关文章
- 2015年ACM长春区域赛比赛感悟
距离长春区域赛结束已经4天了,是时候整理一下这次比赛的点点滴滴了. 也是在比赛前一周才得到通知要我参加长春区域赛,当时也是既兴奋又感到有很大的压力,毕竟我的第一场比赛就是区域赛水平,还是很有挑战性的. ...
- 2015年ACM沈阳网络赛(准备做掉4道:)
Traversal Best Solver Minimum Cut Dividing This Product Excited Database Fang Fang Matches Puzzle Ga ...
- HDU 4763 Theme Section (2013长春网络赛1005,KMP)
Theme Section Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 4764 Stone (2013长春网络赛,水博弈)
Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- HDU 4762 Cut the Cake (2013长春网络赛1004题,公式题)
Cut the Cake Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 4759 Poker Shuffle(2013长春网络赛1001题)
Poker Shuffle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 4768 Flyer (2013长春网络赛1010题,二分)
Flyer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 2012年长春网络赛(hdu命题)
为迎接9月14号hdu命题的长春网络赛 ACM弱校的弱菜,苦逼的在机房(感谢有你)呻吟几声: 1.对于本次网络赛,本校一共6名正式队员,训练靠的是完全的自主学习意识 2.对于网络赛的群殴模式,想竞争现 ...
- Hdu 5439 Aggregated Counting (2015长春网络赛 ACM/ICPC Asia Regional Changchun Online 找规律)
题目链接: Hdu 5439 Aggregated Counting 题目描述: 刚开始给一个1,序列a是由a[i]个i组成,最后1就变成了1,2,2,3,3,4,4,4,5,5,5.......,最 ...
随机推荐
- ElasticSearch-5.0安装head插件
环境 Windows10企业版X64 JDK-1.8 ElasticSearch-5.0.0 node-v4.5.0-x64.msi git客户端 步骤 安装node到D盘.如D:\nodejs. 把 ...
- jquery,php之间的ajax关系以及json
1.最简介写法 function AjaxDepotGoods(id){ $.ajax({ url:"{:U('stock/depot_goods')}", success:fun ...
- nginx 和 IIS 实现负载均衡
Nginx的作用和优点,这里不必多说,今天主要是nginx负载均衡实验,把做的步骤记录下来,作为一个学习笔记吧,也可以给大家做下参考. 1.Nginx安装 1.下载地址:http://nginx.or ...
- zabbix添加监控主机(三)
zabbix添加监控服务器. zabbix添加监控服务器(以添加10.10.100.137为例) (1)创建要监控的主机.点击配置(configuration)–>主机(host) –>创 ...
- 百度编辑器 ueditor 内容编辑自动套P标签,及p标签 替换
如图,红框为回车键和shift+回车 : ===>> ueditor.all.js中: 1: 搜索修改成false:allowDivTransToP: false 再搜索并修改以下 ...
- spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)
spring 封装了非常强大的异常处理机制.本文选取@ControllerAdvice + @ExceptionHandler 这种零配置(全注解),作为异常处理解决方案! @ControllerAd ...
- 大熊君JavaScript插件化开发------(第一季)
一,开篇分析 Hi,大家!大熊君又来了,今天这系列文章主要是说说如何开发基于“JavaScript”的插件式开发,我想很多人对”插件“这个词并不陌生, 有的人可能叫“组件”或“部件”,这不重要,关键是 ...
- [Linux & SVN] SVN介绍及Linux下SVN命令收录
1. SVN是什么? SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移 ...
- Reprint: ADB is Not Recognized as an internal or external command Fix
ADB: Android Debug Bridge http://zacktutorials.blogspot.hk/2013/04/adb-is-not-recognized-as-internal ...
- T-SQL 语句的理解
1.T-SQL中各子句在逻辑上按照以下顺序进行处理 . . . .. .ORDER BY 查询实例: SELECT EMPID, YEAR(ORDERDATE) AS ORDERYEAR, COUNT ...