Topcoder SRM 600 div1题解
日常TC计划正式启动!
Easy(250pts):
题目大意:给你一个集合,里面一堆数,初始数为0,给你一个目标数,你可以选择集合中若干个数进行OR操作来得到目标数。问至少删去多少个数,使得你永远无法达成目标,保证集合最多50个数,每个数<=10^9,且集合中的数两两互不相同。
显然我们要按照每个数的二进制位来考虑,由于所有的数<=10^9,所以最多只有30个二进制位。
如果集合中的一个数,存在某一位使得这个数为1,但是目标数为0,那么这个数一定不能取。
(因为如果取了,那么当前的数这一位就变成了1,然而不存在从1变成0的操作,所以永远无法成为目标数)
对于剩下的数,如果不能达到目标数,那么一定是存在一个二进制位使得目标数为1,其它数都是0。
那么显然只要扫一下就可以了。
时间复杂度O(n*logw),代码如下:
#include <bits/stdc++.h>
using namespace std;
class ORSolitaire
{
public:
int getMinimum(vector <int> numbers,int t)
{
int ans=;
int n=numbers.size();
bool flag[];
for (int i=;i<n;i++)
{
flag[i]=true;
for (int j=;j<=;j++)
if ((numbers[i]&(<<j))&&((t&(<<j))==)) flag[i]=false;
}
for (int i=;i<=;i++)
{
int cnt=;
for (int j=;j<n;j++)
if ((numbers[j]&(<<i))&&flag[j]) ++cnt;
if (t&(<<i)) ans=min(ans,cnt);
}
return ans;
}
};
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),代码如下:
#include <bits/stdc++.h>
#define inf 20000007
using namespace std;
int con[][],a[][];
int n,m;
class PalindromeMatrix
{
int countbit(int s)
{
int st=s,ans=;
while (st>)
{
ans+=(st%==);
st/=;
}
return ans;
}
int deal(int p0,int p1,int q0,int q1)
{
if (p0) p0=;
if (p1) p1=;
if (q0) q0=;
if (q1) q1=;
//p means whether two blocks in the row are the same
//q means whether two blocks in the column are the same
//the aim of the function is just to calculate the possible answer of the blocks of size 2*2
int cnt=;
for (int i=;i<=;i++)
for (int j=;j<=;j++)
cnt+=(con[i][j]==);
if (p0+p1+q0+q1>=) return min(cnt,-cnt);
//all the four blocks must be the same if the sum of p&q are not less than 3
else if(p0+p1+q0+q1==)
{
//there must be exact three blocks that are the same or two blocks in the two rows/columns
//then there will be four conditions
if (p0&&p1) return ((con[][]!=con[][])+(con[][]!=con[][]));
if (q0&&q1) return ((con[][]!=con[][])+(con[][]!=con[][]));
int tot=;
if (p0&&q0) tot=cnt-(con[][]==);
if (p0&&q1) tot=cnt-(con[][]==);
if (p1&&q0) tot=cnt-(con[][]==);
if (p1&&q1) tot=cnt-(con[][]==);
return min(tot,-tot);
} else if (p0+p1+q0+q1==)
{
//there will also be four conditions
int tot=;
if (p0) tot+=(con[][]!=con[][]);
if (p1) tot+=(con[][]!=con[][]);
if (q0) tot+=(con[][]!=con[][]);
if (q1) tot+=(con[][]!=con[][]);
return tot;
}
//then the answer must be 0
else return ;
}
int calc(int rowcnt,int st)
{
int cost[][],f[][];
for (int i=;i<n/;i++)
{
for (int j=;j<=;j++) cost[i][j]=*m;
//x means whether two blocks in the same row are the same
//y means whether two blocks in the same column are the same
for (int x1=;x1<=;x1++)
for (int x2=;x2<=;x2++)
{
int now=;
for (int j=;j<m/;j++)
{
int y1=st&(<<j),y2=st&(<<(m-j-));
con[][]=a[i][j];
con[][]=a[i][m-j-];
con[][]=a[n-i-][j];
con[][]=a[n-i-][m-j-];
now+=deal(x1,x2,y1,y2);
}
cost[i][x1+x2]=min(cost[i][x1+x2],now);
}
}
for (int i=;i<=n/;i++)
for (int j=;j<=rowcnt;j++)
f[i][j]=inf;
f[][]=;
for (int i=;i<=n/;i++)
for (int j=;j<=rowcnt;j++)
for (int k=;k<=&&k<=j;k++)
f[i][j]=min(f[i][j],f[i-][j-k]+cost[n/-i][k]);
return f[n/][rowcnt];
}
public:
int minChange(vector<string> s,int rowcnt,int colcnt)
{
n=s.size(),m=s[].length();
for (int i=;i<n;i++)
for (int j=;j<m;j++)
a[i][j]=s[i][j]-'';
int ans=inf;
for (int st=;st<(<<m);st++)
if (countbit(st)==colcnt) ans=min(ans,calc(rowcnt,st));
return ans;
}
};
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),代码如下:
#include <bits/stdc++.h>
using namespace std;
long long f[][];
class LotsOfLines
{
int gcd(int a,int b)
{
if (b==) return a;
return (gcd(b,a%b));
}
public:
long long countDivisions(int a,int b)
{
memset(f,,sizeof(f));
for (int i=;i<=a;i++)
for (int j=;j<=b;j++)
f[i][j]=f[i-][j]+f[i][j-]-f[i-][j-]+(gcd(i,j)==);
long long ans=+b;
for (int i=;i<a;i++)
for (int j=;j<b;j++)
ans=ans++f[i][j]+f[i][b-j-];
return ans;
}
};
完结撒花~
Topcoder SRM 600 div1题解的更多相关文章
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- Topcoder SRM 607 div1题解
好久没来写了,继续继续... Easy(250pts): //前方请注意,样例中带有zyz,高能预警... 题目大意:给你一个字符串,中间有一些是未知字符,请你求出这个字符串的回文子串个数的期望值.数 ...
- topcoder srm 600 div1
problem1 link 首先,如果一个数字的某一位是1但是$goal$的这一位不是1,那么这个数字是不用管它的.那么对于剩下的数字,只需要统计在$goal$为1的位上,这些数字对应位上也是1的数字 ...
- Topcoder SRM 608 div1 题解
Easy(300pts): 题目大意:有n个盒子,一共有S个苹果,每个盒子有多少个苹果不知道,但是知道每个盒子的苹果下限和上限.现在要至少选择X个苹果,问如果要保证无论如何都能获得至少X个苹果,至少需 ...
- Topcoder SRM 606 div1题解
打卡! Easy(250pts): 题目大意:一个人心中想了一个数,另一个人进行了n次猜测,每一次第一个人都会告诉他实际的数和猜测的数的差的绝对值是多少,现在告诉你所有的猜测和所有的差,要求你判断心中 ...
- Topcoder SRM 605 div1 题解
日常打卡- Easy(250pts): 题目大意:你有n种汉堡包(统统吃掉-),每一种汉堡包有一个type值和一个taste值,你现在要吃掉若干个汉堡包,使得它们taste的总和*(不同的type值的 ...
- Topcoder SRM 604 div1题解
CTSC考完跑了过来日常TC--- Easy(250pts): 题目大意:有个机器人,一开始的位置在(0,0),第k个回合可以向四个方向移动3^k的距离(不能不动),问是否可以到达(x,y),数据满足 ...
- Topcoder SRM 603 div1题解
昨天刚打了一场codeforces...困死了...不过赶在睡前终于做完了- 话说这好像是我第一次做250-500-1000的标配耶--- Easy(250pts): 题目大意:有一棵树,一共n个节点 ...
- Topcoder SRM 601 div1题解
日常TC计划- Easy(250pts): 题目大意:有n个篮子,每个篮子有若干个苹果和橘子,先任取一个正整数x,然后从每个篮子中选出x个水果,把nx个水果放在一起,输出一共有多少种不同的组成方案.其 ...
随机推荐
- php 多维数组相同键值处理合并
一.前言 在实际情况中,有时需要针对多维数组相同键值作相应的处理(四则运算.比较大小等)后才能够使用到实际情况中,现给出三维数组(多维数组可相应拓展)任意多个相同键值处理的函数,以备查阅. 二.代码 ...
- PyQuery网页解析库
from pyquery import PyQuery as pq 字符串初始化: doc = pq(html) URL初始化:doc = pq(url = "···") 文件初始 ...
- C语言数组篇(一)一维数组
0. 数组的两种表现形式 一种是常见的a[10]; //初学者常用 另一种是用指针表示的数组. //实际工程使用.常用于参数传递 ...
- 真是shi
降雨量那题,真踏马shi. 调到还有五个RE不调了. 开始以为map可水后来发现一定要二分查找一下. 这种题没啥营养,不过我发现了我ST表一处错误并打了个板子.就这点用处吧. 这几天做题太少了,每天不 ...
- activity堆栈式管理
package com.chinaCEB.cebActivity.utils; import java.util.Stack; import android.app.Activity; import ...
- echo shell commands as they are executed
http://stackoverflow.com/questions/2853803/in-a-shell-script-echo-shell-commands-as-they-are-execute ...
- imageX.exe
imageX 编辑ImageX 是一个命令行工具,原始设备制造商 (OEM) 和公司可以使用它来捕获.修改和应用基于文件的磁盘映像以进行快速部署.ImageX 可以使用 Windows 映像 (.wi ...
- Monkey、Monkeyrunner之间的区别
Monkey.Monkeyrunner之间的区别 一.Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输 ...
- Python全栈工程师(装饰器、模块)
ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 全栈工程师 Python人工智能从入门到精通 装饰器 decorators(专业提高篇) 装饰 ...
- [OpenCV]Mat类详解
http://blog.csdn.net/yang_xian521/article/details/7107786 Preface Mat:Matrix Mat类可以被看做是opencv中C++版本的 ...