PKUSC 模拟赛 day2 上午总结
今天上午考得不是很好,主要还是自己太弱QAQ
开场第一题给的图和题意不符,搞了半天才知道原来是走日字形的
然后BFS即可
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std; const int maxn=110;
int n,m,a,b,c,d;
int vis[maxn][maxn];
struct pos{
int x,y;
pos(int x=0,int y=0):x(x),y(y){}
};
queue<pos>Q;
int fx[8]={2,2,1,1,-1,-1,-2,-2};
int fy[8]={1,-1,2,-2,2,-2,1,-1}; int BFS(){
if(a==c&&b==d)return 0;
while(!Q.empty())Q.pop();
vis[a][b]=0;Q.push(pos(a,b));
while(!Q.empty()){
pos tmp=Q.front();Q.pop();
for(int i=0;i<8;++i){
int xx=fx[i]+tmp.x,yy=fy[i]+tmp.y;
if(xx<1||yy<1||xx>n||yy>m)continue;
if(vis[xx][yy]!=-1)continue;
if(xx==c&&yy==d)return vis[tmp.x][tmp.y]+1;
vis[xx][yy]=vis[tmp.x][tmp.y]+1;
Q.push(pos(xx,yy));
}
}return -1;
} int main(){
while(scanf("%d%d%d%d%d%d",&n,&m,&a,&b,&c,&d)==6){
memset(vis,-1,sizeof(vis));
int k=BFS();
if(k==-1)printf("impossible\n");
else printf("%d\n",k);
}return 0;
}
第二题给定一个无向图,询问有多少个环不属于任意一个简单环,有多少个环属于至少两个简单环
考试快结束才有点思路,然后码了一发边双一直在挂,最后也没有做出来
考试结束后听lyc说是点双,仔细分析了一下确实是,考试的时候太心急了
改成点双就A了
思路就很显然:点双中如果边数>点数,那么所有点至少属于两个简单环
如果边数<点数,那么不属于任意一个简单环
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int maxn=100010;
int n,m;
int h[maxn],cnt=0;
struct edge{
int to,next;
}G[maxn<<1];
int u,v;
int ans1,ans2;
int pre[maxn],low[maxn];
int vis[maxn],tim;
int dfs_clock,bcc_cnt;
vector<int>V;
stack<int>S; void add(int x,int y){
++cnt;G[cnt].to=y;G[cnt].next=h[x];h[x]=cnt;
}
void Get_ans(){
int sz=V.size(),cnt=0;
for(int i=0;i<sz;++i){
int u=V[i];
for(int j=h[u];j;j=G[j].next){
int v=G[j].to;
if(vis[v]==tim)cnt++;
}
}
cnt>>=1;
if(cnt>sz)ans2+=cnt;
else if(cnt<sz)ans1+=cnt;
} void DFS(int u,int fa){
low[u]=pre[u]=++dfs_clock;
S.push(u);
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(!pre[v]){
DFS(v,u);low[u]=min(low[v],low[u]);
if(low[v]>=pre[u]){
V.clear();tim++;
for(;;){
int now=S.top();S.pop();
vis[now]=tim;V.push_back(now);
if(now==v)break;
}V.push_back(u);vis[u]=tim;
Get_ans();
}
}
else if(fa!=v)low[u]=min(low[u],pre[v]);
}return;
}
void Solve(){
ans1=ans2=0;
memset(pre,0,sizeof(pre));
memset(low,0,sizeof(low));
dfs_clock=bcc_cnt=0;
for(int i=1;i<=n;++i)if(!pre[i])DFS(i,-1);
printf("%d %d\n",ans1,ans2);
}
int main(){
while (scanf("%d%d",&n,&m)==2){
if(!n&&!m)break;
memset(h,0,sizeof(h));cnt=1;
for (int i=1;i<=m;++i){
scanf("%d%d",&u,&v);
u++;v++;
add(u,v);add(v,u);
}Solve();
}
return 0;
}
第三题给定一棵树,询问树上的路径中是否有长度等于k的
直接裸上树分治就可以啦,不到15min码完,1A
用哈希表可以做到O(nlogn)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std; const int maxn=10010;
const int mod=521;
int n,u,v;
int h[maxn],cnt=0;
struct edge{
int to,next,w;
}G[maxn<<1];
int Q[maxn],k;
bool check[maxn],vis[maxn];
int f[maxn],w[maxn],sum,g;
int st[maxn],top;
int dis[maxn];
int a[maxn];
struct HASHMAP{
int h[mod+10],cnt;
int nxt[maxn<<1],st[maxn];
void init(){memset(h,0,sizeof(h));cnt=0;}
int ask(int k){
int key=k%mod;
for(int i=h[key];i;i=nxt[i]){
if(st[i]==k)return true;
}return false;
}
void push(int k){
int key=k%mod;
for(int i=h[key];i;i=nxt[i]){
if(st[i]==k)return;
}
++cnt;nxt[cnt]=h[key];h[key]=cnt;
st[cnt]=k;return;
}
}H;
void add(int x,int y,int z){
cnt++;G[cnt].to=y;G[cnt].next=h[x];G[cnt].w=z;h[x]=cnt;
}
void read(int &num){
num=0;char ch=getchar();
while(ch<'!')ch=getchar();
while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
}
void cmax(int &a,int b){if(b>a)a=b;}
void Get_G(int u,int fa){
f[u]=0;w[u]=1;
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(vis[v]||v==fa)continue;
Get_G(v,u);w[u]+=w[v];
cmax(f[u],w[v]);
}cmax(f[u],sum-w[u]);
if(f[u]<f[g])g=u;
}
void Get_dis(int u,int f){
st[++top]=dis[u];
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(vis[v]||v==f)continue;
dis[v]=dis[u]+G[i].w;
Get_dis(v,u);
}return;
}
void Get_div(int u){
vis[u]=true;H.init();H.push(0);
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(vis[v])continue;
top=0;dis[v]=G[i].w;Get_dis(v,-1);
for(int j=1;j<=top;++j){
for(int now=1;now<=k;++now){
if(st[j]<=a[now])check[now]|=H.ask(a[now]-st[j]);
}
}
for(int j=1;j<=top;++j)H.push(st[j]);
}
for(int i=h[u];i;i=G[i].next){
int v=G[i].to;
if(vis[v])continue;
g=0;sum=w[v];Get_G(v,-1);
Get_div(g);
}return;
} int main(){
while(scanf("%d",&n)==1){
if(!n)break;
memset(h,0,sizeof(h));cnt=0;
for(int i=1;i<=n;++i){
while(scanf("%d",&u)==1){
if(!u)break;
scanf("%d",&v);
add(i,u,v);add(u,i,v);
}
}k=1;
while(scanf("%d",&a[k])==1){
if(!a[k])break;
k++;
}k--;
memset(vis,false,sizeof(vis));
memset(check,false,sizeof(check));
f[0]=0x7fffffff;sum=n;g=0;
Get_G(1,-1);Get_div(g);
for(int i=1;i<=k;++i){
if(check[i])printf("AYE\n");
else printf("NAY\n");
}printf(".\n");
}return 0;
}
第四题给定一个矩阵,询问最大子矩形
直接悬线法裸上就可以了,一开始为了秀技术写单调栈,一直WA
改成悬线法就过了,后来发现自己单调栈有个地方没有+1 QAQ
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn=1010; char s[maxn][maxn];
int map[maxn][maxn];
int n,m;
int T,ans,kase;
int h[maxn],l[maxn],r[maxn]; int Get_ans(int type){
int ans=0;
int L,R;
for(int j=1;j<=m;j++){h[j]=0;l[j]=1;r[j]=m;}
for(int i=1;i<=n;i++){
L=0;R=m+1;
for(int j=1;j<=m;j++){
if(map[i][j]==type){h[j]=0;l[j]=1;L=j;}
else{h[j]++;l[j]=max(l[j],L+1);}
}
for(int j=m;j>=1;j--){
if(map[i][j]==type){r[j]=m;R=j;}
else{r[j]=min(r[j],R-1);ans=max(ans,(h[j]+(r[j]-l[j]+1))*2);}
}
}return ans;
} int main(){
scanf("%d",&T);
while (T--){
ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i][j]=='B')map[i][j]=0;
if(s[i][j]=='R')map[i][j]=1;
}
}
ans=max(ans,Get_ans(1));
ans=max(ans,Get_ans(0));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if((i+j-1)&1)map[i][j]^=1;
}
}
ans=max(ans,Get_ans(1));
ans=max(ans,Get_ans(0));
printf("Case #%d: %d\n",++kase,ans);
}return 0;
}
第五题暂时还没有弄懂
第六题是UVa某题的变形,结果发现自己并不会变形之后的问题
首先很重要的一件事情是蚂蚁的相对位置不会改变
我们不妨把让转换参考系,让向左走的蚂蚁每次走2m/S,向右走的蚂蚁不动
这样很容易就可以计算出向左走的蚂蚁的贡献,向右走的蚂蚁由于颜色一直不动,贡献也是易于计算的
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std; typedef long long LL;
const int maxn=100010;
int n,k,d[maxn],b[maxn],sum[maxn],tmp[maxn];
int now;
bool vis[maxn];
LL ans[maxn];
char s[10]; int main(){
scanf("%d%d",&n,&k);
scanf("%d",&d[n+1]);
for(int i=1;i<=n;++i){
scanf("%d%d%s",&d[i],&b[i],s);
vis[i]=(s[0]=='L');
if(!vis[i])ans[b[i]]+=(d[n+1]-d[i])<<1;
}
for(int i=n;i>=0;--i){
for(int j=0;j<k;++j)ans[j]+=sum[j]*(d[i+1]-d[i]);
if(!vis[i]){
for(int j=0;j<k;++j)tmp[(j+b[i])%k]=sum[j];
for(int j=0;j<k;++j)sum[j]=tmp[j];
}else sum[b[i]]++;
}
for(int i=1;i<=n;++i){
if(vis[i])ans[(now+b[i])%k]+=d[i];
else now=(now+b[i])%k;
}
for(int i=0;i<k;++i){
printf("%lld.",ans[i]>>1);
if(ans[i]&1)printf("5\n");
else printf("0\n");
}return 0;
}
上午只做出了1、3、4,
其中第一题是BFS题目,第三题是树分治的模板题,第四题是悬线法的模板题
第二题太心急了,仔细想想如果发现是点双就可以A了
第五题和第六题是真没看出来
感觉上午发挥的很糟糕,主要是心态问题
PKUSC 模拟赛 day2 上午总结的更多相关文章
- PKUSC 模拟赛 day2 下午总结
终于考完了,下午身体状况很不好,看来要锻炼身体了,不然以后ACM没准比赛到一半我就挂掉了 下午差点AK,有一道很简单的题我看错题面了所以没有A掉 第一题显然是非常丝薄的题目 我们很容易通过DP来O(n ...
- PKUSC 模拟赛 day1 上午总结
思考了一下第二题,觉得有无数种乱搞做法 类似什么bitset压位,MCS染色之类奇怪的做法 然而都是玄学正确性或者玄学复杂度 先放题解把 第一题显然具有单调性,二分就可以啦 O(nlogn),貌似输出 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)
A.九九归一 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2355%20-%20Streaming%20%236%20(NOIP模拟赛day2)/九九归一 题 ...
- PKUSC 模拟赛 题解_UPD
之前挖了两个大坑 一个是day1下午的第二题 另一个是day2上午的第五题 先说day1下午的第二题吧 我们显然不能O(n^2)的dp,所以我们只能算贡献 首先对于任意一个边界点而言,他对答案的贡献路 ...
- PKUSC 模拟赛 day1 下午总结
下午到了机房之后又困又饿,还要被强行摁着看英文题,简直差评 第一题是NOIP模拟赛的原题,随便模拟就好啦 本人模拟功力太渣不小心打错了个变量,居然调了40多分钟QAQ #include<cstd ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告
T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7 ...
- 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】
U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...
随机推荐
- win32开发基础
收集的,正在学习... 跟我一起玩Win32开发(1):关于C++的几个要点 跟我一起玩Win32开发(2):完整的开发流程 跟我一起玩Win32开发(3):窗口的重绘 跟我一起玩Win32开发(4) ...
- Js操作Select大全(取值、设置选中)
Js操作Select是很常见的,也是比较实用的. jquery操作select(取值,设置选中) 每一次操作select的时候,总是要出来翻一下资料,不如自己总结一下,以后就翻这里了. 比如<s ...
- struts2结构图
- Lucene 3.0
http://www.cnblogs.com/forfuture1978/archive/2010/02/22/1671487.html http://www.cnblogs.com/jiekzou/ ...
- Spark菜鸟学习营Day6 分布式代码运行调试
Spark菜鸟学习营Day6 分布式代码运行调试 作为代码调试,一般会分成两个部分 语法调试,也就是确定能够运行 结果调试,也就是确定程序逻辑的正确 其实这个都离不开运行,所以我们说一下如何让开发的S ...
- Newtonsoft.Json同时对多个时间字段以不同的格式序列化
在博客园潜水多年,学到很多,也进步了很多,在这里说声谢谢,是时候给园友分享一点自己的东西,希望和大家一起进步. 之前有个需求要对一张表的多个时间字段进行不同的格式序列化, 在网上没找到相对较好的解决方 ...
- MVC初学 - The type or namespace name 'DbContext' could not be found
问题: The type or namespace name 'DbContext' could not be found (are you missing a using directive or ...
- redis常见性能问题和解决方案?
Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照. Master AOF持久化, ...
- Java并发编程:Lock(上)
在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方 ...
- How to tune SharePoint 2010 Server for better performance?
http://social.technet.microsoft.com/wiki/contents/articles/7926.sharepoint-2010-tips-for-dealing-wit ...