crazy Rows 2009 Round2 A
来源:互联网 发布:公众平台源码搭建 编辑:程序博客网 时间:2024/05/22 12:03
/*crazy Rows 2009 Round2 A给定一个有0 1 组成的矩阵,只允许交换相邻的两行要把矩阵化为下三角矩阵(主对角线上方的元素都是0)最少需要交换几次?输入的矩阵保证总能化成下三角矩阵限制:N∈[1,100]time <=1S内存 <=65535KBEG:1 1 1 0 1 1 1 0 1 0 0 01 1 0 0 ____> 1 1 0 0 _____>···· 1 1 0 01 1 0 0 > 1 0 0 0 >···· 1 1 0 01 0 0 0 1 1 0 0 1 1 1 0 输入3001100010输出 2 (交换1 2 再交换2 3 ) 解: 先说内存 65535KB->64MB 若用int有点浪费空间 不如用char存储矩阵 如果真的一个一个尝试 那么就有N!种 显然时间上不允许 所以我们先暂时考虑: 最后应该把哪一行交换到第一行,第一行应该为全0行或首元素为1其他为0的行而这一行可以交换到任意一行 当有多个满足条件的行时选择离第一行近的行对应的最终费用小因为只能交换相邻的两行假设:X1 X2 X3……Xn 其中X1的元素不应该在第一个位置而这n个元素只有 X2 X3的元素 可以在X1的位置那么若交换 X2 X1则需要一步 然后X3又和X1交换 共两步 得到 X2 X3 X1……若把X3交换到第一行 两步 X2再与X1交换一步 共三步 得到 X3 X2 X1……这两种情况来看 第二种可以看作是第一种移动完了之后 又交换了 X2 X3如果X1 X2 X3之间出现了多个不应该在第一个的元素 是一样的道理 你可能会想 在X1 X2 X3之间插入的元素 万一出现也适合第一个位置的怎么办 其实上述的X1 X2 X3 是有条件的筛选的 每两个之间没有可以当第一个位置的元素如果有 比如 X1 Xm X2 X3中 Xm也符合第一个位置那么 此时应该把 X1 Xm X2 分别当作上述情况的 X1 X2 X3 她们只是代号而已 这个地方懂了 也就明白 为什么当有多个满足条件的行时选择离第一行近的行交换 则对应的最终费用小了。 确定第一行之后就没必要再动它 对于之后的行可以进行相同的处理 每一行中的0 1 数量多少并不重要 重要的是 最后一个1的位置 若将最后的1的位置记录下来 有利于降低复杂度 代码:*/# include <stdio.h># include <stdlib.h># include <time.h># define MAX 60int Swep(int *Flagi,int *Flagj);//交换函数 返回1int main(){char JZ[MAX][MAX+1]={"\0"};//将字符数组初始化为0int i,j,N,Flag[MAX]={0},sum=0,TU;//Flagi记录第i行的最后一个1出现的位置/*****这两行之间的都是生成随即矩阵的 只需要输入行数就能得到随机的符合条件的矩阵********/char MM[MAX+2]={"\0"},SS,QQ[MAX];//这个地方和程序没关系 只是为了生成随机矩阵而设的变量 srand(time(NULL));for(i=0;i<MAX;i++)MM[i]=i+1;//生成矩阵行printf("输入N[1,%d]:",MAX);scanf("%d",&N);//输入矩阵的行数SS=rand()%N; for(i=0;i<N;i++){while(!MM[SS])SS=rand()%N;QQ[i]=SS;MM[SS]=0;} for(i=0;i<N;i++)for(j=0;j<=QQ[i];j++)JZ[i][j]=rand()%4>=1;//生成随机矩阵为了提高1的比重(rand()%6>1)printf("随机矩阵:\n");for(i=0;i<N;i++){for(j=0;j<N;j++)printf("%d",JZ[i][j]);printf("\n");}/*****这两行之间的都是生成随即矩阵的 只需要输入行数就能得到随机的符合条件的矩阵********/for(i=0;i<N;i++){Flag[i]=-1;//每一行先假设没有1的情况下Flagi为-1for(j=0;j<N;j++)if(JZ[i][j]) Flag[i]=j;//这样就记录完每行末尾1的位置}for(i=0;i<N;i++){TU=-1;//TU记录要移动到第i行的行for(j=i;j<N;j++)if(Flag[j]<=i)//一旦寻找到离i最近的行{TU=j; //记录 并执行交换break;}for(j=TU;j>i;j--)//交换{sum+=Swep(&Flag[j],&Flag[j-1]);printf("交换%02d %02d两行\n",j,j+1);//为了快速得到最终结果 可删掉这一行}}printf("至少需要移动%d次\n",sum);return 0;}int Swep(int *Flagi,int *Flagj){int temp=*Flagi;*Flagi=*Flagj;*Flagj=temp;return 1;}
2 0
- crazy Rows 2009 Round2 A
- GCJ 2009 Round2 A (Crazy Rows)
- GCJ--Crazy Rows (2009 Round2 A)
- GCJ 2009 Round2 Problem A. Crazy Rows
- Crazy Rows (GoogleCode Jam 2009 Round2 A)
- GCJ 2009 Round2 A Crazy Rows
- 每天水一水 Crazy Rows (2009 Round2 A) GCJ
- Code Jam 2009 Round2 Problem A. Crazy Rows —— 贪心
- GCJ 2009 Round 2 Problem A. Crazy Rows
- GCJ Round 2 2009 Problem A. Crazy Rows
- 挑战2.7.2 Round 2 2009 A. Crazy Rows 贪心
- Crazy Rows
- GCJ 2009 Problem A. Crazy Rows【位运算要加LL】
- [Code Jam] Crazy Rows
- GCJ Crazy Rows
- GCJ 2009 Round2 A 构造贪心策略
- Google Code Jam 2009 Round2 A (脑洞题)
- GCJ Crazy Rows 水题-贪心
- 【LeetCode】 125. Valid Palindrome
- u8glib自学笔记1
- 20分钟教你使用hexo搭建github博客
- laplacian matrix
- 用Weex实现新闻类app详情页是怎样一种体验?
- crazy Rows 2009 Round2 A
- 在Ubuntu中安装锐捷客户端的替代者 mentohust
- BootStrap FileInput 插件上传使用
- 本地idea项目上传到Git
- nmake (一)
- 求两个数的二进制中有多少个不同的bit位
- git 删除本地分支和远程分支、本地代码回滚和远程代码库回滚
- 2016-java基础篇-分页算法
- 理想的程序员