CTSC考完跑了过来日常TC~~~

Easy(250pts):

题目大意:有个机器人,一开始的位置在(0,0),第k个回合可以向四个方向移动3^k的距离(不能不动),问是否可以到达(x,y),数据满足|x|,|y|<=10^9。

这题还是很简单的嘛,口亨~~~

首先我们只考虑一个方向,于是发现,每一次可以移动3^k的距离或者不动,于是我们发现这样的序列是有且仅有一个的,

于是我们分开考虑x和y,把两个序列全部预处理出来,

然后直接扫一遍就做完了,

时间复杂度O(log|x|)左右吧,代码如下:

 #include <bits/stdc++.h>
using namespace std;
class PowerOfThree
{
public:
string ableToGet(int x, int y)
{
x=abs(x),y=abs(y);
bool check=true;
while (x!=||y!=)
{
if ((x%==)+(y%==)!=) check=false;
if (x%==) x=(x+)/; else x=x/;
if (y%==) y=(y+)/; else y=y/;
}
if (check) return "Possible"; else return "Impossible";
}
};

Medium(550pts):

题目大意:有一棵n个节点的树,有若干节点上有一只狐狸,其它节点没有,所有边的距离为1。现在狐狸要聚集在一起,使得它们形成了一棵树,且每个节点依然最多只有一只狐狸,且移动距离之和最小,输出这个最小值。数据满足n<=50。

我做过的最难的medium吧。。。这题做了我好久好久。。。

首先,最后形成的狐狸一定是一棵树,我们枚举每一个节点i,设i是最后这棵树的root,

我们考虑树形dp,

设f[i][j]表示i这个节点形成的子树中一共放置了j个狐狸,且i这个节点一定有狐狸,且这j个狐狸联通的最优值。

我们考虑如何转移,

假设cur[j]就是当前u这个节点已经处理了若干个儿子的f[u]数组,

于是我们能够得到f[u][i+j]就是从已经处理的若干个儿子中提取i个,从当前正在处理的v节点中提取j个的最优值,

那么已经处理完的若干个儿子对答案的贡献度是cur[i],当前处理的v节点对答案的贡献度是f[v][j]+(u和v这条边对答案的贡献度),

所以f[u][i+j]=cur[i]+f[v][j]+(u和v这条边对答案的贡献度),

所以我们只需要考虑这条边的贡献度就可以了,我们假设size[u]表示u这个节点为根的子树下原始状态下有多少个狐狸,

如果size[v]=j,那么这条边的贡献度就是0;

如果size[v]>j,那么一定有size[v]-j个狐狸从v这个子树出来,那么一定经过这条边,所以这条边贡献度就是size[v]-j;

如果size[v]<j,那么一定有j-size[v]个狐狸进入v这个子树中,它们也一定经过这条边,所以这条边的贡献度就是j-size[v]。

所以无论如何,这条边的贡献度一定是abs(size[v]-j)。

所以我们有f[u][i+j]=cur[i]+f[v][j]+abs(size[v]-j)。

然后边界细节注意一下就可以了,时间复杂度O(n^4),代码如下:

 #include <bits/stdc++.h>
#define Maxn 1007
#define inf 1000000007
using namespace std;
int n,cnt,ans=inf,m;
int last[Maxn],other[Maxn],pre[Maxn],sum[Maxn],size[Maxn];
int f[*Maxn][*Maxn];
int temp[*Maxn];
bool fox[Maxn];
class FoxConnection
{
void insert(int u, int v)
{
other[++cnt]=v,pre[cnt]=last[u],last[u]=cnt;
}
void dfs(int u, int fa)
{
size[u]=fox[u];
int cur[*Maxn];
memset(cur,,sizeof(cur));
for (int q=last[u];q;q=pre[q])
{
int v=other[q];
if (v!=fa)
{
dfs(v,u);
for (int i=;i<=m;i++) temp[i]=inf;
for (int i=;i<=m;i++)
for (int j=;j<=m-i;j++)
temp[i+j]=min(temp[i+j],cur[i]+f[v][j]+abs(size[v]-j));
for (int i=;i<=m;i++) cur[i]=temp[i];
size[u]+=size[v];
}
}
f[u][]=cur[];
for (int i=;i<=m;i++) f[u][i]=cur[i-];
}
int solve(int rt)
{
for (int i=;i<=n;i++)
for (int j=;j<=*n;j++)
f[i][j]=inf;
dfs(rt,-);
return f[rt][m];
}
public:
int minimalDistance(vector <int> A, vector <int> B, string haveFox)
{
n=A.size()+;
for (int i=;i<n;i++) fox[i+]=(haveFox[i]=='Y');
m=;
for (int i=;i<=n;i++) if (fox[i]) ++m;
for (int i=;i<n-;i++)
insert(A[i],B[i]),insert(B[i],A[i]);
for (int i=;i<=n;i++)
ans=min(ans,solve(i));
return ans;
}
};

Hard(1000pts):

这个计算几何题怎么比medium思路简单多了呢。。。

题目大意:给了你n条线段,它们可能有交点,可能有重合,现在把它们视为一个模块,有一张10^9*10^9的长方形纸片,现在复制若干遍这个模块,要求任意两个模块不能相交,要求判断是否可以复制无穷多份。数据满足n<=50。

这题的思路还是很简单的吧,如果能够复制无数份,那么一定是能够往某个方向移动了很小很小的距离,

我们先把所有直线两两处理,

如果重合,直接不用管;

如果没有交点,直接不用管;

如果有一个交点,而且交点不是直线的端点,直接有穷个返回答案;

如果有一个交点,而且交点是直线的端点,那么那个方向一定有角度限制,预处理出角度限制。

所有直线两两处理完了之后,把所有角度限制从小到大扫一遍,然后判定一下就做完了。

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

 #include <bits/stdc++.h>
#define eps 1e-9
#define Maxn 107
using namespace std;
int n,cnt=;
struct point {double x,y;};
struct line {point a,b;};
line a[Maxn];
pair<double,double> cover[Maxn*Maxn*];
class FamilyCrest
{
double cross(double x1 ,double y1, double x2, double y2)
{
return (x1*y2-x2*y1);
}
bool samepoint(point a, point b)
{
//check if point a and point b are the same point
if (fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps) return true;
return false;
}
bool sameline(line a, line b)
{
//check if line a and line b are the same line
double res=cross(a.a.x-a.b.x,a.a.y-a.b.y,b.a.x-b.b.x,b.a.y-b.b.y);
if (fabs(res)<eps) return true;
return false;
}
double sameposition(line a, line b)
{
//check if the whole segment b is on the same direction of line a
//answer>0 means segment b is on the same direction of line a
//answer<0 means segment b has a same point with line a
//answer=0 means segment b has an end point on the line a
double res,res1,res2;
res1=cross(a.b.x-a.a.x,a.b.y-a.a.y,b.a.x-a.a.x,b.a.y-a.a.y);
res2=cross(a.b.x-a.a.x,a.b.y-a.a.y,b.b.x-a.a.x,b.b.y-a.a.y);
res=res1*res2;
return res;
}
void updata(double l, double r)
{
if (l<r)
{
cover[++cnt].first=l,cover[cnt].second=r;
} else
{
cover[++cnt].first=l,cover[cnt].second=M_PI;
cover[++cnt].first=-M_PI,cover[cnt].second=r;
}
}
bool calc(line a, line b)
{
//segment a and segment b are on the same line
if (sameline(a,b)) return true;
//segment a and segment b don't have a same point
if (sameposition(a,b)>eps) return true;
if (sameposition(b,a)>eps) return true;
//segment a and segment b have a same point which is not an end point
if (sameposition(a,b)<-eps) return false;
if (sameposition(b,a)<-eps) return false;
//segment a and segment b have a same point which is an end point
point O,A,B;
//point O is the end point
if (samepoint(a.a,b.a)) O=a.a,A=a.b,B=b.b; else
if (samepoint(a.a,b.b)) O=a.a,A=a.b,B=b.a; else
if (samepoint(a.b,b.a)) O=a.b,A=a.a,B=b.b; else
if (samepoint(a.b,b.b)) O=a.b,A=a.a,B=b.a;
if (cross(A.x-O.x,B.x-O.x,A.y-O.y,B.y-O.y)>eps) swap(A,B);
updata(atan2(A.y-O.y,A.x-O.x),atan2(O.y-B.y,O.x-B.x));
updata(atan2(O.y-A.y,O.x-A.x),atan2(B.y-O.y,B.x-O.x));
return true;
}
public:
string canBeInfinite(vector <int> A, vector <int> B, vector <int> C, vector <int> D)
{
n=A.size();
for (int i=;i<=n;i++)
{
a[i].a.x=A[i-];
a[i].a.y=B[i-];
a[i].b.x=C[i-];
a[i].b.y=D[i-];
}
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
if (!calc(a[i],a[j])) return "Finite";
sort(cover+,cover+cnt+);
if (cover[].first+M_PI>eps) return "Infinite";
if (cover[cnt].second-M_PI<-eps) return "Infinite";
double now=cover[].second;
for (int i=;i<=cnt;i++)
{
if (cover[i].first-now>eps) return "Infinite";
now=cover[i].second;
}
return "Finite";
}
};

完结撒花~

Topcoder SRM 604 div1题解的更多相关文章

  1. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  2. Topcoder SRM 607 div1题解

    好久没来写了,继续继续... Easy(250pts): //前方请注意,样例中带有zyz,高能预警... 题目大意:给你一个字符串,中间有一些是未知字符,请你求出这个字符串的回文子串个数的期望值.数 ...

  3. Topcoder SRM 608 div1 题解

    Easy(300pts): 题目大意:有n个盒子,一共有S个苹果,每个盒子有多少个苹果不知道,但是知道每个盒子的苹果下限和上限.现在要至少选择X个苹果,问如果要保证无论如何都能获得至少X个苹果,至少需 ...

  4. Topcoder SRM 606 div1题解

    打卡! Easy(250pts): 题目大意:一个人心中想了一个数,另一个人进行了n次猜测,每一次第一个人都会告诉他实际的数和猜测的数的差的绝对值是多少,现在告诉你所有的猜测和所有的差,要求你判断心中 ...

  5. Topcoder SRM 605 div1 题解

    日常打卡- Easy(250pts): 题目大意:你有n种汉堡包(统统吃掉-),每一种汉堡包有一个type值和一个taste值,你现在要吃掉若干个汉堡包,使得它们taste的总和*(不同的type值的 ...

  6. Topcoder SRM 603 div1题解

    昨天刚打了一场codeforces...困死了...不过赶在睡前终于做完了- 话说这好像是我第一次做250-500-1000的标配耶--- Easy(250pts): 题目大意:有一棵树,一共n个节点 ...

  7. Topcoder SRM 601 div1题解

    日常TC计划- Easy(250pts): 题目大意:有n个篮子,每个篮子有若干个苹果和橘子,先任取一个正整数x,然后从每个篮子中选出x个水果,把nx个水果放在一起,输出一共有多少种不同的组成方案.其 ...

  8. Topcoder SRM 600 div1题解

    日常TC计划正式启动! Easy(250pts): 题目大意:给你一个集合,里面一堆数,初始数为0,给你一个目标数,你可以选择集合中若干个数进行OR操作来得到目标数.问至少删去多少个数,使得你永远无法 ...

  9. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

随机推荐

  1. Laravel系列 Web

    一.Homestead准备 上一篇文章已经对它的配置进行了说明,下面对Homestead.yaml进行说明 --- ip: "192.168.10.10" memory: 2048 ...

  2. cmd中编译java脚本 (2013-05-02-bd 写的日志迁移

    此前提是已经搭建好了jdk的编译环境! 先写一个java脚本如:建立一个HelloWord.java //public : 表示此类是公共的 一个java文件中只能有一个public类 //class ...

  3. hasattr() & getattr() & setattr()

    Python的hasattr() getattr() setattr() 函数使用方法详解   感谢作者 ---> 原文链接 hasattr(object, name) 判断一个对象里面是否有n ...

  4. Atom使用插件精选(FE)

    [转]原文https://zhuanlan.zhihu.com/p/24753739?refer=AlenQi Atom琳琅满目的插件中,为前端coder推荐一些实用的插件. sync-setting ...

  5. Python语法之com[1][:-7]

    strCom = com[0] + ": " + com[1][:-7] 如上应该是一个字符串合成,最后的[1][:-7],我理解是去除com[1]的最后7个字符. 比如com[0 ...

  6. ADMX Migrator

    实用工具特别推荐ADMX MigratorLance Whitney 下载这篇文章的代码: ADMX Migrator (2765KB) 对于那些 使用组策略的人而言,他们自然非常熟悉如何使用管理模板 ...

  7. 【HTML&CSS】 第一章:DTD文档声明

    <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关 ...

  8. USACO Section2.3 Longest Prefix 解题报告 【icedream61】

    prefix解题报告------------------------------------------------------------------------------------------ ...

  9. 《算法》C++代码 快速排序

    快速排序,简称快排,常称QuickSort.QSort.在排序算法中非常常用,其编程复杂度低,时间复杂度O(NlogN),空间复杂度O(N),执行效率稳定,而且常数很低. 基本思想就是二分,例如你要将 ...

  10. 二叉树 【转】http://blog.csdn.net/sjf0115/article/details/8645991

    //二叉树 #include<iostream> #include<stack> #include<queue> using namespace std; //二叉 ...