hdu4781 Assignment For Princess(构造)

题目链接:hdu4781 Assignment For Princess

题意:n个点m条边,每条有向边的权值分别是1,2,3…m,一个点能到达任意一个点,没有重边和自环,没有任何两条边的权值相同,任意一个有向环的权值和必须是3的倍数,现在需要把这个图输出来。

题解:注意到题目给出的范围m >= n+3,所以一定是可以构造出一个1~n的回路使得权值和为3的倍数的,可以让前n-1条边权值为1~n-1,第n条边(n->1)可以为n, n+1, n+2从而满足题意,后面再连任意两条不相邻的边时,边权模3的大小和原来构造出的第一条回路中两条边的距离大小相等即可。

第一遍自己做没构造成功(失败的代码太丑就不贴了orz),后来参考了这个博客:http://blog.csdn.net/cevaac/article/details/41007703

感觉这类题挺有趣的,我还差得远,加油呐!

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #define CLR(a,b) memset((a),(b),sizeof((a)))
 6 using namespace std;
 7
 8 const int inf = 0x3f3f3f3f;
 9 const int mod = 1e9 + 7;
10 const int N = 101;
11 const int M = 1001;
12 int n, m;
13 int g[M][3];
14 int cnt[3];//边权值模3为0,1,2的个数
15 int d[M];//顶点i到1的距离(1~n构造第一个回路)
16 int main(){
17     int t, i, j, k, x, p;
18     scanf("%d", &t);
19     for(k = 1; k <= t; ++k){
20         printf("Case #%d:\n", k);
21         CLR(d, 0);
22         CLR(cnt, 0);
23         scanf("%d%d", &n, &m);
24         for(i = 1; i <= n-1; ++i){//前n-1条边权为1...n-1
25             printf("%d %d %d\n", i, i+1, i);
26             d[i+1] = d[i] + i;
27         }
28         for(i = n; i <= m; ++i){
29             x = i % 3;
30             cnt[x]++;
31             g[cnt[x]][x] = i;
32         }
33         p = (3 - d[n]%3) %3;//满足构造出的第一个回路权值和为3的倍数
34         printf("%d 1 %d\n", n, g[cnt[p]--][p]);
35         for(i = 1; i <= n-2; ++i){
36             for(j = i+2; j <= n; ++j){
37                 if(i == 1 && j == n)
38                     continue;
39                 p = (d[j] - d[i]) % 3;
40                 if(cnt[p])
41                     printf("%d %d %d\n", i, j, g[cnt[p]--][p]);
42             }
43         }
44     }
45     return 0;
46 }

时间: 2024-11-08 23:22:43

hdu4781 Assignment For Princess(构造)的相关文章

hdu 4781 Assignment For Princess(构造法)

Assignment For Princess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 958    Accepted Submission(s): 286 Special Judge Problem Description Long long ago, in the Kingdom Far Far Away, there li

HDU 4781 Assignment For Princess(YY乱搞)

http://acm.hdu.edu.cn/showproblem.php?pid=4781 Assignment For Princess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 639    Accepted Submission(s): 196 Special Judge Problem Description Long

浅谈C++的virtual 动态绑定。

我们知道C++里 virtual函数可以用来实现多态.继承类可以实现自己的功能来覆盖基类.比如下面这段代码 #include<iostream> #include<string> using namespace std; class BaseA{ public: BaseA(string n):name(n){} string getName() const; virtual void showMyName() const; string name; }; class Derive

《Effective C++》学习笔记(四)

原创文章,转载请注明出处:http://blog.csdn.net/sfh366958228/article/details/38845319 前言 今天给自己订的任务是将<Effective C++>第二章看完,一口气看下来发现量并不大,这一章剩下的内容都较为简短,来看看今天的条款吧. 条款08:别让异常逃离析构函数 如同条款的字面意思,不要让析构函数中抛出异常,这样会使程序出现不明确行为. 举个例子:有一个Widget的自定义类的vector. vector<Widget> v

HDOJ--4781--Assignment For Princess【构造有向图】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4781 题意:给你两个数,n代表顶点个数,m代表边数,要你建一个图,要求: 1. 有向图,且两个点之间最多只有一条边. 2. 边的权值大小为1~m,每个值只能用一次. 3. 任意一个点都可以到达其余各个顶点. 4. 任意一个环的边上权值之和是3的倍数. 5. 不存在自身环. 思路:先从1顶点到n,相邻两个顶点构造一条有向边,权值分别是1.2.3--n-1,n到1也连一条边,取n.n+1或n+2,取满足权值

C++对象模型——&quot;无继承&quot;情况下的对象构造(第五章)

5.2 继承体系下的对象构造 当定义一个object如下: T object; 时,实际上会发生什么事情呢?如果T有一个constructor(不论是由user提供或是由编译器合成),它会被调用.这很明显,比较不明显的是,constructor的调用真正伴随了什么? constructor可能内带大量的隐藏码,因为编译器会扩充每一个constructor,扩充程度视 class T的继承体系而定.一般而言,编译器所做的扩充操作大约如下: 1.记录在member initialization li

【Effective C++ 笔记】构造/析构/赋值

编译器的自动机能 编译器可以暗自为 class 创建 default 构造函数.copy 构造函数.copy assignment 操作符,以及析构函数. 为驳回编译器自动提供的机能,可将成员函数声明为 private 并且不予实现. 例如,如果你打算在一个内含 reference 成员或者 const 成员的 class 内支持赋值操作,必须自己定义 copy assignment 操作符,因为 reference 和 const 变量不可修改. 另外,如果某个 base classes 将

&quot;无继承&quot; 情况下的对象构造

考虑以下代码: Point global; //1) Point Foobar() { Point local; //2) Point *heap = new Point; //3) *heap = local; //4) //...stuff... delete heap; //5) return local; //6) } 1), 2), 3) 为三种不同的对象产生方式: global内存配置, local 内存配置和 heap 内存配置. 4) 把一个object 指定给另一个, 6) 设

C++我们必须要了解的事之具体做法(1)——构造、复制构造、析构、赋值操作符背后的故事

1. C++默认调用哪些函数 当类中的数据成员类型是trival数据类型(就是原c语言的struct类型)时,编译器默认不会创建ctor. copy ctor.assign operator.dctor. 只有在这些函数被调用时,编译器才会创建他们. 这时候我们要自己创建构造函数,初始化内置数据类型.一般我们不需要复制控制函数,当需要时编译器合成的就很好.一般编译器合成的复制控制函数只是简单的复制成员,若能满足要求就不需要自己写. 当类中含有引用.const成员时,必须在初始化列表中初始化成员.