noip2015 day1
不解释,很简单,直接按照题目的方法构造就行了
Code
- #include<iostream>
- #include<cstdio>
- #include<cctype>
- #include<cstring>
- #include<map>
- #include<set>
- #include<queue>
- #include<vector>
- #include<algorithm>
- using namespace std;
- typedef bool boolean;
- template<typename T>
- inline void readInteger(T& u){
- char x;
- while(!isdigit((x = getchar())));
- for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
- ungetc(x, stdin);
- }
- template<typename T>class Matrix{
- public:
- T* p;
- int width;
- int height;
- Matrix():width(), height(){}
- Matrix(int width, int height):width(width), height(height){
- p = new T[width * height];
- }
- T* operator [](int pos){
- return p + pos * width;
- }
- };
- int n;
- Matrix<int> hf;
- int lx, ly;
- inline void init(){
- readInteger(n);
- hf = Matrix<int>(n + , n + );
- }
- inline void solve(){
- memset(hf.p, , sizeof(int) * (n + ) * (n + ));
- hf[][n / + ] = ;
- lx = , ly = n / + ;
- for(int k = ; k <= n * n; k++){
- if(lx == && ly != n){
- lx = n;
- ly++;
- }else if(ly == n && lx != ){
- ly = ;
- lx--;
- }else if(ly == n && lx == ){
- lx++;
- }else if(hf[lx - ][ly + ] == ){
- lx--;
- ly++;
- }else{
- lx++;
- }
- hf[lx][ly] = k;
- }
- for(int i = ; i <= n; i++){
- for(int j = ; j <= n; j++){
- printf("%d ", hf[i][j]);
- }
- putchar('\n');
- }
- }
- int main(){
- freopen("magic.in", "r", stdin);
- freopen("magic.out", "w", stdout);
- init();
- solve();
- return ;
- }
直接Tarjan,当然也可以直接用深搜(貌似要比Tarjan快一点,其实思路还是差不多的)
Code(Tarjan)
- #include<iostream>
- #include<cstdio>
- #include<cctype>
- #include<cstring>
- #include<map>
- #include<set>
- #include<stack>
- #include<queue>
- #include<vector>
- #include<algorithm>
- using namespace std;
- typedef bool boolean;
- template<typename T>
- inline void readInteger(T& u){
- char x;
- while(!isdigit((x = getchar())));
- for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
- ungetc(x, stdin);
- }
- #define smin(a, b) a = min(a, b)
- typedef class Edge{
- public:
- int next;
- int end;
- Edge(const int next = , const int end = ):next(next), end(end){}
- }Edge;
- typedef class MapManager{
- public:
- int *h;
- Edge *edge;
- int ce;
- MapManager():h(NULL), edge(NULL), ce(){}
- MapManager(int points, int edges):ce(){
- h = new int[(const int)(points + )];
- edge = new Edge[(const int)(edges + )];
- memset(h, , sizeof(int) * (points + ));
- }
- inline void addEdge(int from, int end){
- edge[++ce] = Edge(h[from], end);
- h[from] = ce;
- }
- }MapManager;
- #define m_begin(g, i) (g).h[(i)]
- #define m_next(g, i) (g).edge[(i)].next
- #define m_end(g, i) (g).edge[(i)].end
- int *uf;
- int cn;
- stack<int> s;
- int *visitID;
- int *exitID;
- boolean* visited;
- boolean* inStack;
- MapManager g;
- int result;
- inline void getSonMap(int end){
- int counter = ;
- int buf = s.top();
- int first = buf;
- s.pop();
- inStack[buf] = false;
- while(buf != end){
- buf = s.top();
- s.pop();
- inStack[buf] = false;
- uf[buf] = first;
- counter++;
- }
- if(counter > )
- smin(result, counter);
- }
- void Tarjan(int node){
- visitID[node] = exitID[node] = ++cn;
- visited[node] = true;
- inStack[node] = true;
- s.push(node);
- for(int i = m_begin(g, node); i != ; i = m_next(g, i)){
- int& e = m_end(g, i);
- if(!visited[e]){
- Tarjan(e);
- exitID[node] = min(exitID[node], exitID[e]);
- }else if(inStack[e]){
- exitID[node] = min(exitID[node], visitID[e]);
- }
- }
- if(exitID[node] == visitID[node]){
- getSonMap(node);
- }
- }
- int n;
- inline void init(){
- readInteger(n);
- g = MapManager(n, n);
- uf = new int[(const int)(n + )];
- visitID = new int[(const int)(n + )];
- exitID = new int[(const int)(n + )];
- inStack = new boolean[(const int)(n + )];
- visited = new boolean[(const int)(n + )];
- memset(visited, false, sizeof(boolean) * (n + ));
- memset(inStack, false, sizeof(boolean) * (n + ));
- for(int i = , a; i <= n; i++){
- readInteger(a);
- uf[i] = i;
- g.addEdge(i, a);
- }
- }
- inline void solve(){
- result = 0xfffffff;
- for(int i = ; i <= n; i++)
- if(!visited[i])
- Tarjan(i);
- delete[] visitID;
- delete[] exitID;
- printf("%d", result);
- }
- int main(){
- freopen("message.in", "r", stdin);
- freopen("message.out", "w", stdout);
- init();
- solve();
- return ;
- }
Tarjan
dfs的话就记一个访问的时间戳,还要即一个是否在栈中,当时间戳不为初值并且在栈中才说明是环
Code(Dfs)
- #include<iostream>
- #include<cstdio>
- #include<cctype>
- #include<cstring>
- #define smin(a, b) a = min(a, b)
- using namespace std;
- typedef bool boolean;
- template<typename T>
- inline void readInteger(T& u){
- char x;
- while(!isdigit((x = getchar())));
- for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
- ungetc(x, stdin);
- }
- int n;
- int timec;
- int* next;
- int* rank;
- boolean* inStack;
- int result = 0xfffffff;
- void find(int node){
- if(rank[node] != - && inStack[node]){
- smin(result, ++timec - rank[node]);
- return;
- }
- if(rank[node] != - ) return;
- inStack[node] = true;
- rank[node] = ++timec;
- find(next[node]);
- inStack[node] = false;
- }
- int main(){
- freopen("message.in", "r", stdin);
- freopen("message.out", "w", stdout);
- readInteger(n);
- next = new int[(const int)(n + )];
- rank = new int[(const int)(n + )];
- inStack = new boolean[(const int)(n + )];
- memset(rank, -, sizeof(int) * (n + ));
- for(int i = ; i <= n; i++){
- readInteger(next[i]);
- inStack[i] = false;
- }
- for(int i = ; i <= n; i++){
- if(rank[i] == -)
- find(i);
- }
- printf("%d", result);
- return ;
- }
Dfs
思路很简单,搜!不过如果对子、三带一都去搜的话很耗时间,也很耗代码,而且它们是可以直接算出来的
稍微贪一下心,把能带走的都带走,而且从多的开始带。但是双王要记住特殊处理
搜的内容就只包括顺子,只不过注意所有情况都要搜到,因为某些数据顺子即使搜得长,并不是最优的,反
而导致单牌过多。其他都还是没有什么特别坑的细节。
Code
- #include<iostream>
- #include<cstdio>
- #include<cctype>
- #include<cstring>
- #include<map>
- #include<set>
- #include<queue>
- #include<vector>
- #include<algorithm>
- #define smin(a, b) a = min(a, b)
- using namespace std;
- typedef bool boolean;
- template<typename T>
- inline void readInteger(T& u){
- char x;
- while(!isdigit((x = getchar())));
- for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
- ungetc(x, stdin);
- }
- int n;
- int kase;
- int key[] = {, , , , , , , , , , , , , };
- int had[];
- inline void init(){
- memset(had, , sizeof(had));
- for(int i = , a, b; i <= n; i++){
- readInteger(a);
- readInteger(b);
- if(a == ) had[ + b]++;
- else had[key[a]]++;
- }
- }
- int calc(){
- int counter[] = {, , , , };
- for(int i = ; i <= ; i++){
- if(had[i] > ){
- counter[had[i]]++;
- }
- }
- int reter = ;
- boolean aFlag = ;
- if(had[] == && had[] == ){
- aFlag = ;
- }
- while(counter[] && counter[] >= ) reter++, counter[] -= , counter[] -= ;
- while(counter[] && counter[] >= ) reter++, counter[] -= , counter[] -= ;
- while(counter[] && counter[]) reter++, counter[] -= , counter[] -= ;
- while(counter[] && counter[]) reter++, counter[] -= , counter[] -= ;
- while(counter[] && counter[]) reter++, counter[] -= , counter[] -= ;
- if(counter[] >= && aFlag) counter[] -= ;
- return reter + counter[] + counter[] + counter[] + counter[];
- }
- int result;
- void search(int last, int times){
- if(last == ){
- smin(result, times);
- return;
- }
- smin(result, times + calc());
- if(times >= result) return;
- //顺子
- if(last >= ){
- for(int p = ; p >= ; p--){
- for(int i = ; i <= ; i++){
- int k = i;
- while(had[k] >= p && k < ) k++;
- if((k - i) * p >= ){
- for(int j = i; j < k; j++){
- had[j] -= p;
- }
- for(int j = k - ; j >= i; j--){
- if((j - i + ) * p >= )
- search(last - (j - i + ) * p, times + );
- had[j] += p;
- }
- }
- }
- }
- }
- }
- int main(){
- freopen("landlords.in", "r", stdin);
- freopen("landlords.out", "w", stdout);
- readInteger(kase);
- readInteger(n);
- while(kase--){
- init();
- result = n;
- search(n, );
- printf("%d\n", result);
- }
- return ;
- }
noip2015 day1的更多相关文章
- codevs 4511 信息传递(NOIP2015 day1 T2)
4511 信息传递 NOIP2015 day1 T2 时间限制: 1 s 空间限制: 128000 KB 传送门 题目描述 Description 有个同学(编号为 1 到)正在玩一个信息传递的游戏. ...
- 信息传递--NOIP2015 day1 T2--暴力
这道题我用了判联通量加暴力,但联通量判炸了....然后从code[VS]上看到个不错的代码,就拿来了^_^... 基本思路是去掉环外的点,然后走每一个联通块. #include <iostrea ...
- 【 NOIP2015 DAY1 T2 信息传递】带权并查集
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 【NOIP2015 DAY1 T3 】斗地主(landlords)
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- 斗地主 (NOIP2015 Day1 T3)
斗地主 张牌,因为它可以连在K后, 总体思路为 先出炸弹和四带二 再出三带一 再把对牌和单牌出完 记录并更新Answer,后枚举顺子,并继续向下搜索. 注意:弄明白题意,题目描述不太清楚....另外, ...
- 洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2
P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知 ...
- 东方14模拟赛之noip2015/day1/3/神奇的幻方
总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 128000kB 描述 幻方是一种很神奇的N*N 矩阵:它由数字 1,2,3, … …,N*N 构成,且每行.每列及 ...
- 信息传递 NOIP2015 day1 T2
题文: 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮 ...
- noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25
T21 二维数组右上左下遍历 描述 给定一个row行col列的整数数组array,要求从array[0][0]元素开始,按从左上到右下的对角线顺序遍历整个数组. 输入 输入的第一行上有两个整数,依次为 ...
随机推荐
- 【python+opencv】直线检测+圆检测
Python+OpenCV图像处理—— 直线检测 直线检测理论知识: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进 ...
- 启动InnoDB引擎的方法
启动InnoDB引擎的方法 http://down.chinaz.com/server/201207/2090_1.htm 启动InnoDB引擎的方法 Mysql中默认的是MyISAM数据引擎,可惜此 ...
- [git]git版本管理学习记录
今天看到别人用这玩意记录自己的进度, 我也学习了一下. 1,适当的工具会提升效率 2,关注点还是得放在代码本身上. github/gitignore github提供了各种gitignore文件 有p ...
- KMP(http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2772)
#include <stdio.h>#include <string.h>#include <stdlib.h>char a[1000001],b[1000001] ...
- openstack 部署笔记--keystone
控制节点 安装keystone包 # yum install openstack-keystone httpd mod_wsgi keystone配置文件 # vim /etc/keystone/ke ...
- ID和Name
ID和Name都可以用来标识一个标记,Javascript分别有两个方法getElementById和getElementByName来定位Dom节点. 区别如下: 1.我们知道在网页做Post提交时 ...
- linux 启动引导流程
课程大纲: Linux引导流程 Linux运行级别 Linux启动服务管理 GRUB配置与应用 启动故障分析与解决 系统引导流程 1.固件firmware(CMOS(固化在硬件上的程序与硬件统称)/B ...
- reduce()方法
1.reduce()方法概述 reduce方法有两个参数,第一个参数是一个callback,用于针对数组项的操作:第二个参数则是传入的初始值,这个初始值用于单个数组项的操作.需要注意的是,reduce ...
- JS中的对象数组
<html> <head> <title>对象数组的字符串表示</title> <script type="text/javascrip ...
- 服务器修改用户密码注意iis部署的网站问题
当服务器修改用户密码时,需要修改iis上部署的跟此用户权限有关的所有网站,选择网站——右击——应用程序管理——高级设置——物理路径凭证——特定用户——修改用户名和密码.