2661: [BeiJing wc2012]连连看
2016-01-21 15:35
302 查看
Description
凡是考智商的题里面总会有这么一种消除游戏。不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏。我们的规则是,给出一个闭区间[a,b]中的全部整数,如果其中某两个数x,y(设x>y)的平方差x2-y2是一个完全平方数z2,并且y与z互质,那么就可以将x和y连起来并且将它们一起消除,同时得到x+y点分数。那么过关的要求就是,消除的数对尽可能多的前提下,得到足够的分数。快动手动笔算一算吧。Input
只有一行,两个整数,分别表示a,b。Output
两个数,可以消去的对数,及在此基础上能得到的最大分数。Sample Input
1 15Sample Output
2 34HINT
对于30%的数据,1<=a,b<=100对于100%的数据,1<=a,b<=1000
题解: http://blog.csdn.net/aarongzk/article/details/50302219 code:
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<algorithm> #define maxn 2005 #define maxm 1000000 #define inf 1061109567 using namespace std; char ch; bool ok; void read(int &x){ for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); if (ok) x=-x; } int a,b; bool bo1[maxn],bo2[maxn],bo[maxn]; struct flow{ int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm]; int dis[maxn],head,tail,list[maxn],tmp,totflow,totcost; bool bo[maxn]; void init(){s=0,t=(b<<1)+1,tot=1,memset(now,0,sizeof(now));} void put(int a,int b,int c,int d){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c,cost[tot]=d;} void add(int a,int b,int c,int d){put(a,b,c,d),put(b,a,0,-d);} void spfa(){ memset(bo,0,sizeof(bo)); memset(dis,63,sizeof(dis)); head=0,tail=1,list[1]=s,dis[s]=0,bo[s]=1; while (head!=tail){ if (++head==maxn) head=1; int u=list[head]; for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (val[p]&&dis[v]>dis[u]+cost[p]){ dis[v]=dis[u]+cost[p]; if (!bo[v]){ if (++tail==maxn) tail=1; list[tail]=v,bo[v]=1; } } bo[u]=0; } } int dfs(int u,int rest,int totval){ bo[u]=1; if (u==t){totcost+=rest*totval;return rest;} int ans=0; for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p]) if (val[p]&&!bo[v]&&dis[v]==dis[u]+cost[p]){ int d=dfs(v,min(rest,val[p]),totval+cost[p]); val[p]-=d,val[p^1]+=d,ans+=d,rest-=d; } return ans; } bool relax(){ int d=inf; for (int u=s;u<=t;u++) if (bo[u]) for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (val[p]&&!bo[v]) d=min(d,dis[u]+cost[p]-dis[v]); if (d==inf) return false; for (int u=s;u<=t;u++) if (!bo[u]) dis[u]+=d; return true; } void work(){ spfa(),totflow=totcost=0; do{ do{ memset(bo,0,sizeof(bo)); tmp=dfs(s,inf,0),totflow+=tmp; }while (tmp); }while (relax()); } }f; int main(){ read(a),read(b),f.init(); for (int i=a;i<=b;i++) for (int j=a;j<i;j++){ int t=round(sqrt(i*i-j*j)); if (t*t==i*i-j*j&&__gcd(j,t)==1) bo[i]=1,bo[j]=1,f.add(i,j+b,1,-i-j),f.add(j,i+b,1,-i-j); } for (int i=a;i<=b;i++) if (bo[i]) f.add(f.s,i,1,0); for (int i=a;i<=b;i++) if (bo[i]) f.add(i+b,f.t,1,0); f.work(); printf("%d %d\n",f.totflow>>1,(-f.totcost)>>1); return 0; }
相关文章推荐
- 浏览器地址栏欺骗漏洞背后
- Xcode7.2 No such module 'Cocoa'问题
- Closures--闭包
- 正则表达式
- java 执行bat批处理文件 并关闭cmd窗口
- 用HorizontalScrollView实现listview的左右滑动
- XMPP协议的原理介绍
- C各个类型的大小
- c#设计模式-单例模式(面试题)
- extjs combobox 如何获取点击事件
- ORA-01565: error in identifying file '+DATA/ORACLE/spfileORACLE.ora'
- leetcode之happy number
- 剖析C++编程中friend关键字所修饰的友元函数和友元类
- Android中使用【microlog4】进行日志存储
- Mybatis学习笔记(3)之高级功能
- 发布mvc报错:403.14-Forbidden Web 服务器被配置为不列出此目录的内容
- java 并发插入数据到oracle
- Recursion--递归
- 第一篇 前言
- 如何设置memcached来共享php的session