Ural_1169_Pairs
此题略坑。。。
思路:把N个点分成m若干个联通子图,然后用m-1个桥把这m个联通子图连接起来即可。
若每个联通子图内部都是完全图也符合题意,但答案却是Wrong Answer,只有把每个联通子图内部当成环来输出才通过,这是本题的一个坑,一个Bug!!!
另外联通子图中点的个数不能等于2(如果不明白请读者认真思考5遍)
第三个要注意的地方就是输出时每个联通子图只能有一个点与外界连接,不能有两个!!!(如果不明白请读者认真思考10遍)
关键在于确定每个联通子图中点的个数,若第i个联通子图中的点个数为a[i],则Σa[i]=N,且Σ(a[i]*(n-a[i]))=2K
即Σa[i]2 =N2 - 2K ,Σa[i]=N
方法有两种:DP 和 搜索
DP:
set<int>s[105];
s[i]是和为i的若干个数的平方和的集合。
dp[105][10005]
若干个数和为i,平方和为j,则dp[i][j]为这些数中最大的那个
s[0].insert(0);
for (int i=0;i<100;++i)
for (set<int>::iterator it=s[i].begin();it!=s[i].end();++it)
for (int j=i?dp[i][*it]:1;j<=100-i;++j)
{
if (j==2) continue;
s[i+j].insert((*it)+j*j);
dp[i+j][(*it)+j*j]=j;
}
搜索:
找出一组数,和为N,平方和为N2 - 2K :
若找到了这样的一组数,返回数的个数,否则返回0
int check(int x,int n,int depth)
{
if (n*n<x) return 0;
for (int i=(depth>1)?a[depth-1]:1;i<=n && x-i*i>=n-i;++i)
{
if (i==2) continue;
a[depth]=i;
if (i==n && i*i==x) return depth;
int y=check(x-i*i,n-i,depth+1);
if (y) return y;
}
return 0;
}
完整代码如下:
DP版:
/*************************************************************************
> File Name: D.cpp
> Author: Chierush
> Mail: qinxiaojie1@gmail.com
> Created Time: 2013年08月02日 星期五 09时05分46秒
************************************************************************/ #include <iostream>
#include <cstring>
#include <cstdlib>
#include <set>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm> #define LL long long
#define LLU unsigned long long using namespace std; int a[101],cnt;
int dp[105][10005]; set<int>s[105]; int main()
{
s[0].insert(0);
for (int i=0;i<100;++i)
for (set<int>::iterator it=s[i].begin();it!=s[i].end();++it)
for (int j=i?dp[i][*it]:1;j<=100-i;++j)
{
if (j==2) continue;
s[i+j].insert((*it)+j*j);
dp[i+j][(*it)+j*j]=j;
}
int n,k;
scanf("%d%d",&n,&k);
int x=n*n-2*k;
if (x<n)
{
puts("-1");
return 0;
}
if (!dp[n][x]) puts("-1");
else
{
int p=n,q=x;
for (;;)
{
if (!p || !q) break;
int o=dp[p][q];
a[cnt++]=o;
p-=o,q-=o*o;
}
sort(a,a+cnt);
for (int i=1;i<cnt;++i) a[i]+=a[i-1];
for (int i=1;i<a[0];++i) printf("%d %d\n",i,i+1);
if (a[0]>1) printf("%d %d\n",1,a[0]);
for (int i=1;i<cnt;++i)
{
printf("%d %d\n",a[i-1],a[i]);
for (int j=a[i-1]+1;j<a[i];++j) printf("%d %d\n",j,j+1);
if (a[i]-a[i-1]>1) printf("%d %d\n",a[i-1]+1,a[i]);
}
}
return 0;
}
搜索版:
/*************************************************************************
> File Name: D.cpp
> Author: Chierush
> Mail: qinxiaojie1@gmail.com
> Created Time: 2013年08月02日 星期五 09时05分46秒
************************************************************************/ #include <iostream>
#include <cstring>
#include <cstdlib>
#include <set>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm> #define LL long long
#define LLU unsigned long long using namespace std; int a[101],cnt; int check(int x,int n,int depth)
{
if (n*n<x) return 0;
for (int i=(depth>1)?a[depth-1]:1;i<=n && x-i*i>=n-i;++i)
{
if (i==2) continue;
a[depth]=i;
if (i==n && i*i==x) return depth;
int y=check(x-i*i,n-i,depth+1);
if (y) return y;
}
return 0;
} int main()
{
int n,k;
scanf("%d%d",&n,&k);
int x=n*n-2*k;
if (x<n)
{
puts("-1");
return 0;
}
int u=check(x,n,1);
if (!u) puts("-1");
else
{
for (int i=2;i<=u;++i) a[i]+=a[i-1];
for (int i=1;i<a[1];++i)
printf("%d %d\n",i,i+1);
if (a[1]>1) printf("%d %d\n",1,a[1]);
for (int i=2;i<=u;++i)
{
printf("%d %d\n",a[i-1],a[i]);
for (int j=a[i-1]+1;j<a[i];++j)
printf("%d %d\n",j,j+1);
if (a[i]-a[i-1]>1) printf("%d %d\n",a[i-1]+1,a[i]);
}
}
return 0;
}
Ural_1169_Pairs的更多相关文章
随机推荐
- MATLAB Toolbox Path Cache is out of date and is not being used的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 使用mcc编译MATLAB\R2009a\extern\examples\compiler目录下的hello.m,编译 ...
- 用表来管理SQLServer中的扩展属性(描写叙述)
数据字典是个好东东,对于开发.维护很重要. 但Sql Server中写描写叙述确实不方便,怎样化繁为简.批量地添加改动扩展属性呢? 添加2个表和5个存储过程.2个触发器.1个表值函数就好了. 把以下的 ...
- Numpy Usage Introduction
Reference : http://my.oschina.net/u/175377/blog/74406 试验性的Numpy教程 原文来自Tentative NumPy Tutorial 目录 先决 ...
- 使用ant对项目进行多渠道打包时遇到问题记录
1.打包成功后,打开apk时,会出现闪退的现象解决方法:1.配置好ant后,先把项目正常运行后,再打包,如有问题见第2步 2.找到项目中build.xml,然后右键,选择Run As - ...
- QT之二级菜单(二级菜单的箭头可以使用QSS设置图片)
QT之二级菜单 QT之二级菜单 开场白 效果图 上代码 可参考文章 下代码 结尾 开场白 今天我们一起来了解下,在我们QT中,二级菜单是如何实现的,在上篇我们学习了QT之系统托盘,QT之自定义菜单, ...
- Java中文件的上传与下载
文件的上传与下载主要用到两种方法: 1.方法一:commons-fileupload.jar commons-io.jar apache的commons-fileupload实现文件上传,下载 [u ...
- 4 WCF中的RPC和OneWay
1 创建两个控制台项目 WcfService和WcfClient 在wcfService项目中新建一个wcf服务的文件项(HomeService)会自动附带生成一个IHomeService.cs的文件 ...
- 还在使用vc6.0吗??vs2010吧
每个人在面对新的事物的时候,总是充满了排斥感,当vista和win7来临的时候,我们还在留恋xp,说xp是如何的好,win7是如何的不给力,当然,我们必须承认,xp是一款优秀的操作系统,这个我们无法否 ...
- 2 abp 领域层创建实体
领域层: LearningMpaAbp.Core项目 基础服务层:EntityFramework对应的项目 1 在领域层新建Tasks文件夹 在文件夹下新建Task类 但是注意 Task类必须要继 ...
- NPM镜像设置方法!
使用npm安装一些包失败了的看过来(npm国内镜像介绍) 发布于 2012-4-26 04:19 最后一次编辑是 2013-12-11 23:21 这个也是网上搜的,亲自试过,非常好用! 镜像使用方法 ...