HDU3682 To Be an Dream Architect
来源:互联网 发布:英语翻译软件哪个好 编辑:程序博客网 时间:2024/06/05 15:08
To Be an Dream Architect
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2505 Accepted Submission(s): 706
Cobb uses a simple 3D imagination game to test whether a candidate has the potential to be an dream architect. He lets the candidate imagine a cube consisting of n×n×n blocks in a 3D coordinate system as Figure 1. The block at bottom left front corner is marked (1, 1, 1) and the diagonally opposite block is marked (n, n, n). Then he tells the candidate that the blocks on a certain line are eliminated. The line is always parallel to an axis. After m such block eliminations, the candidate is asked to tell how many blocks are eliminated. Note that one block can only be eliminated once even if it is on multiple lines.
Here is a sample graph according to the first test case in the sample input:
In each test case, the first line contains two integers n and m( 1 <= n <= 1000, 0 <= m <= 1000).,meaning that the cube is n x n x n and there are m eliminations.
Each of the following m lines represents an elimination in the following format:
axis_1=a, axis_2=b
where axis_i (i=1, 2) is ‘X’ or ‘Y’, or ‘Z’ and axis_1 is not equal to axis_2. a and b are 32-bit signed integers.
23 2Y=1,Z=3X=3,Y=110 2X=3,Y=3Y=3,Z=3
519
lcy&zhengfeng
(先吐槽下,比个赛过程中被叫出去开会2次(都还开了很长时间)。中国会多,美国税多。。。)
这题吧,昨晚YY出一种方法,结合容斥原理的思想,n*m'(m要去重复的,代码中的k就是m') - 2条直线相交的对数(记作代码中的f)+3条直线相交的对数(记作代码中的all) =答案
首先我用数组xy[](平行于Z轴,x值为下标,y值为xy[x][]的值),
yz[](平行于X轴,y值为下标,z值为xy[x][]的值),
zx[](平行于Y轴,z值为下标,X值为xy[x][]的值);
去存储输入的直线。
for(j=0;j<m;j++){getchar();scanf("%c=%d,%c=%d",&p,&a,&q,&b);if((p=='X'&&q=='Y')||(p=='Y'&&q=='X')){if(p=='X'&&q=='Y') xy[a].push_back(b);elsexy[b].push_back(a);} else if((p=='Y'&&q=='Z')||(p=='Z'&&q=='Y')){if(p=='Y'&&q=='Z')yz[a].push_back(b);elseyz[b].push_back(a);}else if((p=='Z'&&q=='X')||(p=='X'&&q=='Z')){if(p=='Z'&&q=='X')zx[a].push_back(b);elsezx[b].push_back(a);}}
然后使用sort排序,结合vector的unique和erase删除重复的输入。
for(i=1;i<=1000;i++){if(xy[i].size()){sort(xy[i].begin(),xy[i].end());xy[i].erase(unique(xy[i].begin(),xy[i].end()),xy[i].end());}if(yz[i].size()){sort(yz[i].begin(),yz[i].end());yz[i].erase(unique(yz[i].begin(),yz[i].end()),yz[i].end());}if(zx[i].size()){sort(zx[i].begin(),zx[i].end());zx[i].erase(unique(zx[i].begin(),zx[i].end()),zx[i].end());}}
接下来分别计算m',f,all;
m':
m' 只需累加每个vector的size();
f:
累加具有相同x | y | z 值得之间对数,实现方法会在下面的all中提到。
all:
vec数组 下标 值 (请注意下标和值的含义,上面有提到)
xy[] i xy[i][]
yz[] j yz[j][]
zx[] k zx[k][]
如果2直线有交点,那么 xy[i][]=j || yz[j][]=k || zx[k][]=i ; 结果累加可以得到f;
如果3直线有交点,那么 xy[i][]=j && yz[j][]=k && zx[k][]=i ; 结果累加可以得到all;
for(i=1;i<=1000;i++){if(xy[i].size()){k+=xy[i].size();//printf("%d %d\n",xy[i][0],xy[i].size());for(int g=0;g<xy[i].size();g++){f+=yz[xy[i][g]].size();for(int s=0;s<yz[xy[i][g]].size();s++){for(int r=0;r<zx[yz[xy[i][g]][s]].size();r++){if(zx[yz[xy[i][g]][s]][r]==i)all++;}} }}if(yz[i].size()){k+=yz[i].size();for(int g=0;g<yz[i].size();g++)f+=zx[yz[i][g]].size();}if(zx[i].size()){k+=zx[i].size();for(int g=0;g<zx[i].size();g++)f+=xy[zx[i][g]].size();} }
输出结果就可以了:
printf("%d\n",n*k-f+all);
贴出完整代码:
#include<iostream>#include<stdio.h>#include<vector>#include<queue>#include<stack>#include<algorithm>#include<math.h>#include<string>#include<map>#include<set>#include<string.h>using namespace std;vector<int> xy[1001],yz[1001],zx[1001];int main(){//freopen("in.txt","r",stdin);int t;scanf("%d",&t);while(t--){int a,b,i,j,k=0,n,m,all=0,f=0;char p,q;//memset(xy,0,sizeof(xy));//memset(yz,0,sizeof(yz));//memset(zx,0,sizeof(zx));scanf("%d%d",&n,&m);for(i=0;i<=1000;i++){xy[i].clear();yz[i].clear();zx[i].clear();}for(j=0;j<m;j++){getchar();scanf("%c=%d,%c=%d",&p,&a,&q,&b);if((p=='X'&&q=='Y')||(p=='Y'&&q=='X')){if(p=='X'&&q=='Y') xy[a].push_back(b);elsexy[b].push_back(a);} else if((p=='Y'&&q=='Z')||(p=='Z'&&q=='Y')){if(p=='Y'&&q=='Z')yz[a].push_back(b);elseyz[b].push_back(a);}else if((p=='Z'&&q=='X')||(p=='X'&&q=='Z')){if(p=='Z'&&q=='X')zx[a].push_back(b);elsezx[b].push_back(a);}}for(i=1;i<=1000;i++){if(xy[i].size()){sort(xy[i].begin(),xy[i].end());xy[i].erase(unique(xy[i].begin(),xy[i].end()),xy[i].end());}if(yz[i].size()){sort(yz[i].begin(),yz[i].end());yz[i].erase(unique(yz[i].begin(),yz[i].end()),yz[i].end());}if(zx[i].size()){sort(zx[i].begin(),zx[i].end());zx[i].erase(unique(zx[i].begin(),zx[i].end()),zx[i].end());}}for(i=1;i<=1000;i++){if(xy[i].size()){k+=xy[i].size();//printf("%d %d\n",xy[i][0],xy[i].size());for(int g=0;g<xy[i].size();g++){f+=yz[xy[i][g]].size();for(int s=0;s<yz[xy[i][g]].size();s++){for(int r=0;r<zx[yz[xy[i][g]][s]].size();r++){if(zx[yz[xy[i][g]][s]][r]==i)all++;}} }}if(yz[i].size()){k+=yz[i].size();for(int g=0;g<yz[i].size();g++)f+=zx[yz[i][g]].size();}if(zx[i].size()){k+=zx[i].size();for(int g=0;g<zx[i].size();g++)f+=xy[zx[i][g]].size();}}//printf("%d %d %d\n",k,f,all);printf("%d\n",n*k-f+all);} return 0;}
结果:0 ms
注:我参考了一下的博文,觉得博主讲很好,让我学到很多。
http://blog.csdn.net/angelniu1024/article/details/12784261
另外,刚刚发现hdu排名的优先级是(time->memory->code len),很希望知道大神们的消耗的存储空间怎么这么小,求大家指点一下,谢谢!
- HDU3682 To Be an Dream Architect
- hdu3682 To Be an Dream Architect
- hdu 3682(To Be an Dream Architect)
- hdu 3682To Be an Dream Architect
- hdu 3682 To Be an Dream Architect
- vector 3682 To Be an Dream Architect
- HDOJ 3682 To Be an Dream Architect
- HDOJ 3682 To Be an Dream Architect 暴力
- HDU 3682 To Be an Dream Architect (hash)
- hdu 3682 To Be an Dream Architect (hash)
- hdu 3682 To Be an Dream Architect hash
- [水+思路] hdu 3682 To Be an Dream Architect
- Hdu 3682 To Be an Dream Architect(Hash)
- To Be an Dream Architect(2010年ACM亚洲预选赛杭州赛区第三题))
- HDU 3682To Be an Dream Architect(统计规律题目 三线相交bug)
- HDU 3682 To Be an Dream Architect (STL去重--思路题目)
- To be a Java Architect
- A-Z Guide to Being an Architect
- 单播多播和广播
- IIS跨域设置,用localhost进自己的网站进不去,用127.0.0.1可以
- 红黑树
- Delphi中判断一个字符的位置在字符串开头或者末尾
- 破解“无法复制粘贴”
- HDU3682 To Be an Dream Architect
- 记录我对cygwin的个性化设置
- 总结个人网站成功运营的11条原则
- VC Tips
- QThread架构中QObject间通讯常见误区澄清
- how to use Dom to create and remove element
- 大数阶乘思考
- C中.h头文件的写法
- 进程池实现客户端连接请求程序