博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Topcoder SRM 600 div1题解
阅读量:4941 次
发布时间:2019-06-11

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

日常TC计划正式启动!

Easy(250pts):

题目大意:给你一个集合,里面一堆数,初始数为0,给你一个目标数,你可以选择集合中若干个数进行OR操作来得到目标数。问至少删去多少个数,使得你永远无法达成目标,保证集合最多50个数,每个数<=10^9,且集合中的数两两互不相同。

显然我们要按照每个数的二进制位来考虑,由于所有的数<=10^9,所以最多只有30个二进制位。

如果集合中的一个数,存在某一位使得这个数为1,但是目标数为0,那么这个数一定不能取。

(因为如果取了,那么当前的数这一位就变成了1,然而不存在从1变成0的操作,所以永远无法成为目标数)

对于剩下的数,如果不能达到目标数,那么一定是存在一个二进制位使得目标数为1,其它数都是0。

那么显然只要扫一下就可以了。

时间复杂度O(n*logw),代码如下:

1 #include 
2 using namespace std; 3 class ORSolitaire 4 { 5 public: 6 int getMinimum(vector
numbers,int t) 7 { 8 int ans=50; 9 int n=numbers.size();10 bool flag[57];11 for (int i=0;i

Medium(600pts):

题目大意:给你一个n*m的01矩阵,你需要尽可能少地改变矩阵中的数(0变成1,1变成0)使得矩阵中至少有r行是回文串,c列是回文串,输出最少操作次数。其中2<=n,m<=14,数据保证n和m都是偶数。

这应该是这场最烦的题目了吧,如果你会玄学优化,说不定可以搜过去~~~(大雾)

我们枚举2^m种的情况,每一列有回文或者不回文的情况,接下来我们考虑使用dp。

考虑dp的状态,如果只是一列一列的进行状态的转移,那么这样显然是不太好做的,因为你不知道这一行是否回文。

于是我们考虑首尾两行,两行两行进行转移。

我们可以先预处理出cost数组,cost[i][j]表示第i行和第n-1-i行一共有j个串是回文串的最小代价。(所以j=0,1,2)

这里我们显然可以通过枚举出2*2的小矩阵,对于2*2我们只要手判就可以了。

接下来考虑转移dp数组,f[i][j]表示前i行和后i行一共有j个串是回文串的最小代价。

于是我们有f[i][j]=min(f[i][j],f[i-1][j-k]+cost[i][k]),中间一些细节(特别是下标)考虑清楚就好了。

时间复杂度O(2^n*n^2),代码如下:

1 #include 
2 #define inf 20000007 3 using namespace std; 4 int con[5][5],a[57][57]; 5 int n,m; 6 class PalindromeMatrix 7 { 8 int countbit(int s) 9 { 10 int st=s,ans=0; 11 while (st>0) 12 { 13 ans+=(st%2==1); 14 st/=2; 15 } 16 return ans; 17 } 18 int deal(int p0,int p1,int q0,int q1) 19 { 20 if (p0) p0=1; 21 if (p1) p1=1; 22 if (q0) q0=1; 23 if (q1) q1=1; 24 //p means whether two blocks in the row are the same 25 //q means whether two blocks in the column are the same 26 //the aim of the function is just to calculate the possible answer of the blocks of size 2*2 27 int cnt=0; 28 for (int i=0;i<=1;i++) 29 for (int j=0;j<=1;j++) 30 cnt+=(con[i][j]==1); 31 if (p0+p1+q0+q1>=3) return min(cnt,4-cnt); 32 //all the four blocks must be the same if the sum of p&q are not less than 3 33 else if(p0+p1+q0+q1==2) 34 { 35 //there must be exact three blocks that are the same or two blocks in the two rows/columns 36 //then there will be four conditions 37 if (p0&&p1) return ((con[0][0]!=con[0][1])+(con[1][0]!=con[1][1])); 38 if (q0&&q1) return ((con[0][0]!=con[1][0])+(con[0][1]!=con[1][1])); 39 int tot=0; 40 if (p0&&q0) tot=cnt-(con[1][1]==1); 41 if (p0&&q1) tot=cnt-(con[1][0]==1); 42 if (p1&&q0) tot=cnt-(con[0][1]==1); 43 if (p1&&q1) tot=cnt-(con[0][0]==1); 44 return min(tot,3-tot); 45 } else if (p0+p1+q0+q1==1) 46 { 47 //there will also be four conditions 48 int tot=0; 49 if (p0) tot+=(con[0][0]!=con[0][1]); 50 if (p1) tot+=(con[1][0]!=con[1][1]); 51 if (q0) tot+=(con[0][0]!=con[1][0]); 52 if (q1) tot+=(con[0][1]!=con[1][1]); 53 return tot; 54 } 55 //then the answer must be 0 56 else return 0; 57 } 58 int calc(int rowcnt,int st) 59 { 60 int cost[57][5],f[57][57]; 61 for (int i=0;i
s,int rowcnt,int colcnt) 94 { 95 n=s.size(),m=s[0].length(); 96 for (int i=0;i

Hard(900pts):

题目大意:给你两个整数A,B,求直线y=ax+b将平面分成了多少个部分,(a=0,1...A-1,b=0,1,...B-1)其中1<=A,B<=1200。

这是个很棒棒的公式题。

我们考虑把所有的直线一条一条加进来,那么我们只需要统计出每加进来一条直线会多出多少个平面就可以了。

对于直线y=ax+b,显然它不会和y=ax+c,其中c不等于b的直线相交。

于是我们只需要考虑直线y=ax+b和y=cx+d其中c<a且d<B的直线相交。

我们还需要注意到一个细节就是,如果有三条直线交在了同一个点上,那么对于答案的贡献度会减少1,

换句话说,我们要考虑的本质不是有多少直线相交,而是它们会相交出多少个交点。

考虑直线y=ax+b和y=cx+d,它们的交点P,那么Xp=(d-b)/(a-c),

我们将Xp视为p/q,那么我们只需要考虑本质不同的p/q有多少就可以了,

我们来观察一下p和q的范围,

其中p=d-b,那么p在-b~B-b的范围内,而q=a-c,于是q在1~a的范围内。

那么本质不同的p/q是什么呢,也就是p/q的数值不同,那么只需要考虑p和q互质的情况就可以了。

这里可以用莫比乌斯反演呢,但是A,B<=1200,所以直接暴力就好了。

所以这一题我们先预处理出1~i,1~j中有多少对数互质,接下来直接统计答案就可以了。

时间复杂度O(A^2),代码如下:

1 #include 
2 using namespace std; 3 long long f[1507][1507]; 4 class LotsOfLines 5 { 6 int gcd(int a,int b) 7 { 8 if (b==0) return a; 9 return (gcd(b,a%b));10 }11 public:12 long long countDivisions(int a,int b)13 {14 memset(f,0,sizeof(f));15 for (int i=1;i<=a;i++)16 for (int j=1;j<=b;j++)17 f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+(gcd(i,j)==1);18 long long ans=1+b;19 for (int i=1;i

完结撒花~

 

转载于:https://www.cnblogs.com/Tommyr7/p/6796250.html

你可能感兴趣的文章
020-安装centos6.5后的生命历程
查看>>
面试介绍项目经验(转)
查看>>
创建并设置ASP.NET的会话状态服务器(SQL State Server)
查看>>
<metro>Google的验证
查看>>
SQL中NUMERIC和DECIMAL的区别
查看>>
安卓课程设计:微课表
查看>>
Oracle 表的分组操作
查看>>
在OS X上的Intllij Idea中配置GlassFish
查看>>
用查表法快速转换yv12到RGB【转】
查看>>
使用公钥登录SSL
查看>>
hdu 1290_献给杭电五十周年校庆的礼物
查看>>
Nginx 入门
查看>>
openCR-用ROS代码点亮LED的方法
查看>>
豆瓣电影api
查看>>
BufferedInputStream和FileInputStream的区别
查看>>
二阶段之六
查看>>
微博爬虫 python
查看>>
中石油 【递归】普通递归关系
查看>>
vue报错Error in render: "TypeError: Cannot read property '0' of undefined"
查看>>
silverlight 隐藏ChildWindow 右上角的关闭按钮
查看>>