topcoder srm 707 div1
1 构造一个棋盘,长宽n,m不超过50,每个格子为障碍或者非障碍两种,使得从(0,0)到(n-1,m-1)的最短路为给定的值k。
思路:如果k小于等于98,那么一定存在没有障碍的棋盘满足要求。否则,最后的路径可以如下图所示(白色为障碍)。假设一开始向左弯曲到最左侧的次数为x,最后一次向左弯曲的长度为y,然后枚举矩形的长宽,判断是否等于k即可。

2 将s变成t,每次操作可以将s加上a,或者将s乘上b。问最少的操作次数。
思路:b为0或者1是单独讨论。现在假设b大于1.设一共经过了m次乘操作,第i次乘法操作前进行的加法操作次数为$p_{i}$,那么最后得到的值为$((((s+p_{0}a)b+p_{1}a)b+...)b+p_{m-1}a)b+p_{m}$$=sb^{m}+a\sum_{i=0}^{m}p_{i}b_{m-i}$。所以首先枚举m,那么$\sum_{i=0}^{m}p_{i}b_{m-i}=\frac{t-sb^{m}}{a}$。这时候贪心即可确定各个$p_{i}$,答案为$m+\sum_{i=0}^{m}p_{i}$
void up(long long &x,long long y)
{
if(x==-1||x>y) x=y;
} class MultiplyAddPuzzle {
public:
long long minimalSteps(long long s, long long t, long long a, long long b)
{
if(s==t) return 0;
if(b==0)
{
if(t==0) return 1;
if(a==0) return -1;
if(t>s&&(t-s)%a==0) return (t-s)/a;
if(t%a==0) return t/a+1;
return -1;
}
if(b==1)
{
if(a==0) return -1;
if(t>s&&(t-s)%a==0) return (t-s)/a;
return -1;
} long long p[63];
p[0]=1;
for(int i=1;i<63;++i) p[i]=p[i-1]*b;
long long ans=-1; for(int m=0;m<62;++m)
{
if(a==0)
{
if(t%p[m]==0&&t/p[m]==s) up(ans,m);
}
else
{
if(t/p[m]<s) break;
if((t-p[m]*s)%a==0)
{
long long S=(t-p[m]*s)/a;
long long curAns=m;
for(int i=m;i>=0;--i)
{
curAns+=S/p[i];
S-=S/p[i]*p[i];
}
up(ans,curAns);
}
}
if(b>t/p[m]) break;
}
return ans;
}
};
3 有一个棋盘,棋盘的某些位置上放有棋子。有依次执行的若干操作,每个操作是将其中的一个棋子移动a到相邻的某个格子b上。每次移动时,要求a上必须有一个棋子,b上没有棋子。对于一个操作序列,若存在某个初始的棋盘使得该操作序列的每个操作都合法,那么称该操作序列合法。求最少删掉操作序列的多少个操作可以使得上下的序列合法。
思路: $u$移动到$v$,增加三条边,如下图所示。所有边流量均为1,代价除了-1外都为0.源点到所有的点连边,代表每个节点最后的节点到汇点连边。最后求最小费用最大流。费用为非负时结束查找可行流。得到的费用的绝对值就是不需要删除的操作。

#include <map>
#include <string>
#include <stdio.h>
#include <vector>
#include <set>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stack>
#include <queue>
using namespace std; const int N=5000; const int INF=10000000; struct node
{
int u,v,flow,cost,next;
}; node edges[N*100];
int head[N],e; void add(int u,int v,int flow,int cost)
{
edges[e].u=u;
edges[e].v=v;
edges[e].cost=cost;
edges[e].flow=flow;
edges[e].next=head[u];
head[u]=e++;
} void Add(int u,int v,int flow,int cost)
{
add(u,v,flow,cost);
add(v,u,0,-cost);
} int C[N],F[N],pre[N];
int visit[N]; int SPFA(int s,int t)
{
memset(pre,-1,sizeof(pre));
queue<int> Q;
Q.push(s);
int i;
for(i=0;i<=t;i++) C[i]=INF,F[i]=0,visit[i]=0;
int u,v,c,f;
C[s]=0; F[s]=INF;
while(!Q.empty())
{
u=Q.front();
Q.pop(); visit[u]=0;
for(i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
c=edges[i].cost;
f=edges[i].flow;
if(f>0&&C[v]>C[u]+c)
{
C[v]=C[u]+c;
F[v]=min(F[u],f);
pre[v]=i;
if(!visit[v])
{
Q.push(v);
visit[v]=1;
}
}
}
}
if(C[t]>=0) return 0;
return F[t];
} int MCMF(int s,int t)
{
int ans=0,i,temp,x;
while(temp=SPFA(s,t))
{
for(i=t;i!=s;i=edges[pre[i]].u)
{
x=pre[i];
ans+=temp*edges[x].cost;
edges[x].flow-=temp;
edges[x^1].flow+=temp;
}
}
return ans;
} int get(int x,int y)
{
return x*60+y;
} int p[5000]; class AncientGameRecord {
public:
int minimalRemove(int n, int m, vector <int> x, vector <int> y, string d)
{
memset(head,-1,sizeof(head));
const int K=(int)x.size();
int cnt=0;
for(int i=0;i<K;++i)
{
int x1=x[i],x2=x[i];
int y1=y[i],y2=y[i];
if(d[i]=='D') ++x2;
if(d[i]=='U') --x2;
if(d[i]=='L') --y2;
if(d[i]=='R') ++y2; if(x2==-1||x2==n||y2==-1||y2==m) continue;
int c1=get(x1,y1);
int c2=get(x2,y2);
Add(p[c1],cnt+1,1,0);
Add(p[c2],cnt+2,1,0);
Add(cnt+1,cnt+2,1,-1);
p[c1]=cnt+1;
p[c2]=cnt+2;
cnt+=2;
}
int sink=cnt+1;
for(int i=0;i<n;++i) for(int j=0;j<m;++j) if(p[get(i,j)])
{
Add(p[get(i,j)],sink,1,0);
}
return K+MCMF(0,sink);
}
};
topcoder srm 707 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 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 ...
- topcoder srm 575 div1
problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...
随机推荐
- 日线做多,15min做空的情况收集
- javascript(三):对象
对象(object)是javascript中很重要的数据类型.对象是“键值对”的集合,同时也是无序的.(注意:对象结尾处有分号) var ob1={ a1:'name',//a1可以加引号或者不加 a ...
- SolidWorks242个使用技巧
1 您可以使用 CTRL+TAB 键循环进入在 SolidWorks 中打开的文件. 2 使用方向键可以旋转模型.按 CTRL 键加上方向键可以移动模型.按 ALT 键加上方向键可以将模型沿顺时针或逆 ...
- Helter Skelter (扫描线 + 离散化 + 树状数组)
扫描线:按照其中一个区间的标记为pos,然后左区间标记d为正影响,有区间标记d为负影响,然后根据所有的pos排序.pos从小扫到大,那么对于某一个区间一定会被扫过2次,那么经过2次之后就只剩下中间那一 ...
- sqoop从hive导入数据到mysql时出现主键冲突
今天在将一个hive数仓表导出到mysql数据库时出现进度条一直维持在95%一段时间后提示失败的情况,搞了好久才解决.使用的环境是HUE中的Oozie的workflow任何调用sqoop命令,该死的o ...
- Hive中实现group concat功能(不用udf)
在 Hive 中实现将一个字段的多条记录拼接成一个记录: hive> desc t; OK id string str string Time taken: 0.249 seconds hive ...
- Linux基础命令---验证组文件grpck
grpck grpck指令可以验证组文件“/etc/group”和“/etc/gshadow”的完整性.检查的内容包括:正确的字段数.唯一有效的组名称.有效的组标识符.成员和管理员的有效列表.“/et ...
- 前端框架VUE----nodejs中npm的使用
NPM是什么? 简单的说,npm就是JavaScript的包管理工具.类似Java语法中的maven,gradle,python中的pip. 安装 傻瓜式的安装. 第一步:打开https://node ...
- Python爬虫——小说
#encoding:utf8 import re import urllib2 url = 'http://www.23us.com/html/55/55304/' request = urllib2 ...
- 自写Jquery插件 Tab
原创文章,转载请注明出处,谢谢!https://www.cnblogs.com/GaoAnLee/p/9067017.html 每每看到别人写的Jquery插件,自己也试着学习尝试,终有结果,废话不多 ...