博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nordic Collegiate Programming Contest 2016
阅读量:6591 次
发布时间:2019-06-24

本文共 3732 字,大约阅读时间需要 12 分钟。

A Artwork

输入:

n,m表示原图为n*m个白色方格,输入x1,y1,x2,y2表示将x1,y1,x2,y2涂为黑色。

输出:

对于每个x1,y1,x2,y2输入当前图案白色联通块的数目。

思路:

先维护得到最后图案的形状,包括每个黑色方块的厚度。

对于每个x1,y1,x2,y2倒序访问,将其对应位置的黑色还原为白色。通过上下左右的联通关系,更新并查集得到每组的答案。

#include
using namespace std;struct sc{ int a,b,c,d;} edg[10010];int p[1100100],g[1010][1010],ans[10010];int dx[]= {
0,1,-1,0};int dy[]= {
1,0,0,-1};int n,m,q,cnt=0,k=0;int f(int x){ return x==p[x]?x:p[x]=f(p[x]);}void u(int a,int b){ int x=f(a),y=f(b); p[x]=y;}int id(int x,int y){ return x*(m+2)+y+1;}int main(){ scanf("%d %d %d",&n,&m,&q); memset(g,0,sizeof g); for(int i=0; i<=n+1; i++) for(int j=0; j<=m+1; j++) { p[id(i,j)]=id(i,j); if(!i||!j|i>n||j>m)g[i][j]=1; } for(int i=0; i
=0; i--)printf("%d\n",ans[i]);}
View Code

反思:

场上心里闪过并查集的念头,但是只想到了对于黑色进行并查集,没有从一个角度看问题,比如反过来看,看答案的对应面,比如补集,或者倒着获得答案。

数组开小了, 应该算清楚每个数组的范围。

B Bless You Autocorrect!

输入:

n,m表示下面有n,m个串,n表示手机里的字典词按照出现的顺序表示优先级,m表示你想输入的单词。

输出:

对于每个你想输入的单词,输出最小打出它需要的按键次数。

思路:

用字典树来存储单词,字典树(树上的每一个串的子串都会有一个id),通过这些id和每个串每打一个按键可以得到的另外一个串建立双向边。

跑一遍bfs即可获得每个串可以打出需要的最小按键数量。

#include
using namespace std;const int maxn=1e6;char s[maxn];int tot=0,tree[30][maxn],edg=0,head[maxn],dp[maxn],cnt[maxn],vis[maxn];struct sc{ int to,nxt;}p[6*maxn];void add(int a,int b){ p[edg]={b,head[a]},head[a]=edg++;}void inser(){ int l=strlen(s),nxt=0; for(int i=0;i
q; for(q.push(0);!q.empty();q.pop()) { int v=q.front(); for(int i=head[v];~i;i=p[i].nxt) { int u=p[i].to; if(!vis[u]) { vis[u]++; dp[u]=dp[v]+1; q.push(u); } } }}int ans(){ int l=strlen(s),mi=l,nxt=0,u; for(int i=0;i
View Code

反思:

这道题对于每个状态的互相转移关系,可以看作类似最短路,需要一点点思维吧(是不是可以用map映射id来做这道题呢)。

C Card Hand Sorting

输入:

扑克牌的花色和点数。

输出:

相同花色放在一起且牌成递增或者递减,最小需要的操作数。

思路:

扑克牌最后形成的结果只有1<<4*4的全排列中,枚举之

#include
using namespace std;pair
s[200];int spoke[5][20],cnt[5],vis[5],p[5],n,lis[60],ans=0x3f3f3f3f;map
m;map
,int>mm;void init(){ m['s']=0,m['h']=1,m['d']=2,m['c']=3; m['T']=10,m['J']=11,m['Q']=12,m['K']=13,m['A']=14; memset(spoke,0,sizeof spoke); memset(cnt,0,sizeof cnt); memset(vis,0,sizeof vis); for(int i=2; i<=9; i++)m['0'+i]=i;}bool cmp(int a,int b){ return a>b;}void dfs(int inde){ if(inde==4) { for(int i=0;i<16;i++) { for(int j=0;j<4;j++)sort(spoke[j],spoke[j]+cnt[j]); for(int j=0;j<4;j++)if((1<
View Code

反思:

场上的时候一直在想怎么直接的贪心思路,对于答案情况很少的题可以直接枚举之。

D Daydreaming Stockbroker

 思维,水题

E Exponial

数学,没补

F Fleecing the Raffle

推公式,水题

G Game Rank

模拟,水题

 H Highest Tower

输入:

n个矩形的长宽

输出:

严格递减落成塔形,塔的最高高度

思路:

建树,出为底,入为高,出读最多的为1,(deg-1)是他最为高出现的次数,(deg-1)*h为他对于答案的贡献,如果图案是一个树,那么可以选择一个最大的点作为根节点,得到的答案最大,如果图案是一个图,那么形成的关系是唯一的直接计算即可。

#include
using namespace std;const int axn=550000+10;struct sc{ int to,nxt;} p[2*axn];int head[2*axn],edg=0,id=1,deg[axn],fm[axn],vis[axn],maxn;long long ans=0,degg;map
m;void add(int a,int b){ deg[a]++,deg[b]++; p[edg]= {b,head[a]},head[a]=edg++; p[edg]= {a,head[b]},head[b]=edg++;}void dfs(int u){ if(vis[u])return ; vis[u]=1; degg+=deg[u]-2; maxn=max(maxn,fm[u]); ans+=(long long)(deg[u]-1)*fm[u]; for(int i=head[u];~i;i=p[i].nxt) dfs(p[i].to);}int main(){ memset(vis,0,sizeof vis); memset(head,-1,sizeof head); //freopen("i.txt","r",stdin); //freopen("o.txt","w",stdout); int n,x,y; scanf("%d",&n); for(int i=0; i
View Code

反思:

对于涉及矩形长宽的题,思考能否把边看成点建图解决。

I Interception

没补

J Jumbled Compass

思维,水题。

K Keeping the Dogs Apart

蓝书有板子,还没研究。

 

转载于:https://www.cnblogs.com/ncc62497/p/9809962.html

你可能感兴趣的文章
查看源代码Source not found及在eclipse中配置jdk的src.zip源代码
查看>>
document.all用法
查看>>
uniGUI试用笔记(二)
查看>>
HOG特征-理解篇
查看>>
Microsoft.AlphaImageLoader滤镜解说
查看>>
extjs_02_grid(显示本地数据,显示跨域数据)
查看>>
超过响应缓冲区限制
查看>>
ubuntu 下安装 matplotlib
查看>>
webservice的几个简单概念
查看>>
underscore 1.7.0 api
查看>>
C# CheckedListBox控件的使用方法
查看>>
spring Transaction Management --官方
查看>>
iOS开发-清理缓存功能的实现
查看>>
IS_ERR、PTR_ERR、ERR_PTR
查看>>
html5 canvas 奇怪的形状垂直渐变
查看>>
mac java环境
查看>>
lamp 一键安装
查看>>
SQL Server 2008 收缩日志(log)文件
查看>>
UICollectionView基础
查看>>
SSAS中CUBE行权限数据级权限控制
查看>>