topcoder srm 360 div1
problem1 link
(1)$n \neq m$时,假设$n<m$,那么同一行中的$m$个数字必定都相等。
(2)$n=m$时,要满足任意的$i_{1},i_{2},j_{1},j_{2},A[i_{1}][j_{1}]+A[i_{2}][j_{2}]=A[i_{1}][j_{2}]+A[i_{2}][j_{1}]$
import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class SumOfSelectedCells { public String hypothesis(String[] table) {
final String YES="CORRECT";
final String NO="INCORRECT";
final int n=table.length;
int m=-1;
int[][] g=new int[22][22];
for(int i=0;i<n;++i) {
String[] t=table[i].split("\\W+");
if(m==-1) {
m=t.length;
}
else {
assert m==t.length;
}
for(int j=0;j<m;++j) {
g[i][j]=Integer.valueOf(t[j]);
}
}
if(n!=m) {
if(n<m) {
for(int i=0;i<n;++i) {
for(int j=1;j<m;++j) {
if(g[i][0]!=g[i][j]) {
return NO;
}
}
}
}
else {
for(int j=0;j<m;++j) {
for(int i=1;i<n;++i) {
if(g[0][j]!=g[i][j]) {
return NO;
}
}
}
}
}
else {
for(int i1=0;i1<n;++i1) {
for(int i2=i1+1;i2<n;++i2) {
for(int j1=0;j1<m;++j1) {
for(int j2=j1+1;j2<m;++j2) {
if(g[i1][j1]+g[i2][j2]!=g[i1][j2]+g[i2][j1]) {
return NO;
}
}
}
}
}
}
return YES;
}
}
problem2 link
仅当相邻时无解。有解时答案最大为4.因为可以将其中的一个围住。那么只需要检测小于4时是否可以。这时,可以暴力枚举然后判断连通性。
import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class PrinceOfPersia { static class pair {
public int first;
public int second; public pair() {}
public pair(int first,int second) {
this.first=first;
this.second=second;
}
} int[][] visit=null;
int index=0;
int sx=-1,sy=-1,ex=-1,ey=-1; String[] maze=null; final int[] dx={0,0,1,-1};
final int[] dy={1,-1,0,0};
int n,m; List<pair> empty=null; boolean dfs(int x,int y) {
if(x==ex&&y==ey) {
return true;
}
if(x<0||x>=n||y<0||y>=m||maze[x].charAt(y)=='#') {
return false;
}
if(index==visit[x][y]) {
return false;
}
visit[x][y]=index;
for(int i=0;i<4;++i) {
if(dfs(x+dx[i],y+dy[i])) {
return true;
}
}
return false;
} int cal() {
++index;
if(!dfs(sx,sy)) {
return 0;
}
for(int i=0;i<empty.size();++i) {
++index;
visit[empty.get(i).first][empty.get(i).second]=index;
if(!dfs(sx,sy)) {
return 1;
}
} for(int i=0;i<empty.size();++i) {
for(int j=i+1;j<empty.size();++j) {
++index;
visit[empty.get(i).first][empty.get(i).second]=index;
visit[empty.get(j).first][empty.get(j).second]=index;
if(!dfs(sx,sy)) {
return 2;
}
}
} for(int i=0;i<empty.size();++i) {
for(int j=i+1;j<empty.size();++j) {
for(int k=j+1;k<empty.size();++k) {
++index;
visit[empty.get(i).first][empty.get(i).second]=index;
visit[empty.get(j).first][empty.get(j).second]=index;
visit[empty.get(k).first][empty.get(k).second]=index;
if(!dfs(sx,sy)) {
return 3;
}
}
}
}
return 4;
} public int minObstacles(String[] maze) { this.maze=maze;
n=maze.length;
m=maze[0].length();
visit=new int[n][m];
empty=new ArrayList<>();
for(int i=0;i<n;++i){
for(int j=0;j<m;++j) {
if(maze[i].charAt(j)=='P') {
if(sx==-1) {
sx=i;
sy=j;
}
else {
ex=i;
ey=j;
}
}
else if(maze[i].charAt(j)=='.') {
empty.add(new pair(i,j));
}
}
}
if(sx==ex&&Math.abs(sy-ey)==1||sy==ey&&Math.abs(sx-ex)==1) {
return -1;
}
return cal();
}
}
problem3 link
设$m$ 为给出的数字个数.对于一个凸包,假设顶点大于3,那么去掉任意一个顶点后仍是凸包。所以:
(1)$m\geq 6$时,若为奇数只需要添加一个数字(这时可以暴力),为偶数不需要添加;
(2)$m<6$时,需要添加$6-m$个数字。$m=2,3,4,5$时可以暴力;$m=0$时答案为$1,1,1,2,2,1$,$m=1$时,若给出的数字为1则答案为$1,1,2,2,1$,否则答案为$1,1,1,1,2$
那么,剩下的问题就是判断凸包,只需判断:(1)任意三个点角度小于180;(2)任意两条边不相交(这个只需要判断$y$连续严格增大的顶点段的个数以及$y$严格减小的连续顶点段的个数,为凸包时这些段数最大为3)
import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class ConvexArray { static class point {
public long x;
public long y; public point() {}
public point(long x,long y) {
this.x=x;
this.y=y;
}
public point add(point a) {
return new point(x+a.x,y+a.y);
}
public point substract(point a) {
return new point(x-a.x,y-a.y);
}
public long crossMultiply(point a) {
return x*a.y-y*a.x;
} } boolean check(List<Integer> list) {
final int n=list.size()>>1;
List<point> g=new ArrayList<>();
for(int i=0;i<n;++i) {
g.add(new point(list.get(i<<1),list.get(i<<1|1)));
}
long a=0;
for(int i=0;i<n;++i) {
a+=g.get(i).crossMultiply(g.get((i+1)%n));
}
if(a==0) {
return false;
}
if(a<0) {
int ll=0,rr=n-1;
while(ll<rr) {
point p=g.get(ll);
point q=g.get(rr);
g.set(ll,q);
g.set(rr,p);
++ll;
--rr;
}
}
for(int i=0;i<n;++i) {
point p=g.get(i);
point q=g.get((i+1)%n);
point r=g.get((i+2)%n);
if(q.substract(p).crossMultiply(r.substract(p))<=0) {
return false;
}
}
int num=0;
for(int i=0;i<n;) {
if(g.get(i).y<g.get((i+1)%n).y) {
++num;
while(g.get(i).y<g.get((i+1)%n).y) {
++i;
if(i==n) {
break;
}
}
}
else if(g.get(i).y>g.get((i+1)%n).y) {
++num;
while(g.get(i).y>g.get((i+1)%n).y) {
++i;
if(i==n) {
break;
}
}
}
else {
++i;
}
}
if(num>3) {
return false;
}
return true;
} public int[] getEnding(int[] beginning) {
final int n=beginning.length;
if(n>=6) {
List<Integer> list=new ArrayList<>();
for(int i=0;i<n;++i) {
list.add(beginning[i]);
}
if(n%2==1) {
list.add(0);
for(int i=1;i<=50;++i){
list.set(list.size()-1,i);
if(check(list)) {
return new int[]{i};
}
}
return new int[]{-1};
}
else {
if(check(list)) {
return new int[0];
}
else {
return new int[]{-1};
}
}
}
if(n==0) {
return new int[]{1,1,1,2,2,1};
}
if(n==1) {
final int x=beginning[0];
if(x==1) {
return new int[]{1,1,2,2,1};
}
return new int[]{1,1,1,1,2};
}
List<Integer> list=new ArrayList<>();
for(int i=0;i<n;++i) {
list.add(beginning[i]);
}
while(list.size()<6) {
list.add(0);
}
if(dfs(n,list)) {
int[] result=new int[6-n];
for(int i=n;i<6;++i) {
result[i-n]=list.get(i);
}
return result;
}
return new int[]{-1};
} boolean dfs(int t,List<Integer> list) {
if(t==6) {
return check(list);
}
for(int i=1;i<=50;++i) {
list.set(t,i);
if(dfs(t+1,list)) {
return true;
}
}
return false;
}
}
topcoder srm 360 div1的更多相关文章
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- topcoder srm 515 div1
problem1 link 暴力枚举即可. problem2 link 一共有24小时,所以最多有24个顾客.设$f[x][y][z]$表示还剩下$x$把刀,现在时间是$y$,以及来过的顾客集合为$z ...
- topcoder srm 714 div1
problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...
- topcoder srm 738 div1 FindThePerfectTriangle(枚举)
Problem Statement You are given the ints perimeter and area. Your task is to find a triangle wi ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
Problem Statement The Happy Letter game is played as follows: At the beginning, several players ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
- TopCoder SRM 605 DIV1
604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...
随机推荐
- Lambda引言
Lambda表达式:可以方便我们把方法当做参数传递 package airycode_java8.nice1; import org.junit.Test; import java.util.*; / ...
- 水题B
国际象棋的棋盘是黑白相间的8 * 8的方格,棋子放在格子中间.如下图所示: 王.后.车.象的走子规则如下: 王:横.直.斜都可以走,但每步限走一格. 后:横.直.斜都可以走,每步格数不受限制. 车:横 ...
- GBDT:梯度提升决策树
http://www.jianshu.com/p/005a4e6ac775 综述 GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Ad ...
- C# 实现生产者消费者队列
开发过程中经常会碰到这样的场景:需要从一个地方获取一些数据,然后处理数据并将其保存在数据库中. 1 2 3 4 5 6 7 8 9 10 private void FetchData() {} pri ...
- jQuery安装
http://www.runoob.com/jquery/jquery-install.html 网页中添加jQuery: 方法一:可以从http://jquery.com/download/ 下载j ...
- 泛型List、HashTable
从最开始接触的数组,到非泛型集合类(ArrayList.HashTable.Queue.Stack).泛型集合类(List<T>.Dictionary<T>.Queue< ...
- Linux基础命令---杀死进程killall
killall killall可以根据名字来杀死进程,它会给指定名字的所有进程发送信息.如果没有指定信号名,则发送SIGTERM.信号可以通过名称(例如-HUP或-SIGHUP)或数字(例如-1)或选 ...
- ESB(Enterprise Service Bus)企业服务总线介绍
ESB(Enterprise Service Bus)企业服务总线介绍 ESB全称为Enterprise Service Bus,即企业服务总线.它是传统中间件技术与XML.Web服务等技术结合的产物 ...
- P5015 标题统计
P5015 标题统计 ‘ ’ 不等于空格,空格是个字符 代码: #include<iostream> #include<cstdio> #include<cmath& ...
- Java中高级面试必问之多线程TOP50(含答案)
以下为大家整理了今年一线大厂面试被问频率较高的多线程面试题,由于本人的见识局限性,所以可能不是很全面,也欢迎大家在后面留言补充,谢谢. 1.什么是线程? 2.什么是线程安全和线程不安全? 3.什么是自 ...