不解释,很简单,直接按照题目的方法构造就行了

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的更多相关文章

  1. codevs 4511 信息传递(NOIP2015 day1 T2)

    4511 信息传递 NOIP2015 day1 T2 时间限制: 1 s 空间限制: 128000 KB 传送门 题目描述 Description 有个同学(编号为 1 到)正在玩一个信息传递的游戏. ...

  2. 信息传递--NOIP2015 day1 T2--暴力

    这道题我用了判联通量加暴力,但联通量判炸了....然后从code[VS]上看到个不错的代码,就拿来了^_^... 基本思路是去掉环外的点,然后走每一个联通块. #include <iostrea ...

  3. 【 NOIP2015 DAY1 T2 信息传递】带权并查集

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  4. 【NOIP2015 DAY1 T3 】斗地主(landlords)

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  5. 斗地主 (NOIP2015 Day1 T3)

    斗地主 张牌,因为它可以连在K后, 总体思路为 先出炸弹和四带二 再出三带一 再把对牌和单牌出完 记录并更新Answer,后枚举顺子,并继续向下搜索. 注意:弄明白题意,题目描述不太清楚....另外, ...

  6. 洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2

    P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知 ...

  7. 东方14模拟赛之noip2015/day1/3/神奇的幻方

    总时间限制:  10000ms 单个测试点时间限制:  1000ms 内存限制:  128000kB 描述 幻方是一种很神奇的N*N 矩阵:它由数字 1,2,3, … …,N*N 构成,且每行.每列及 ...

  8. 信息传递 NOIP2015 day1 T2

    题文: 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮 ...

  9. noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25

    T21 二维数组右上左下遍历 描述 给定一个row行col列的整数数组array,要求从array[0][0]元素开始,按从左上到右下的对角线顺序遍历整个数组. 输入 输入的第一行上有两个整数,依次为 ...

随机推荐

  1. Oracle备份恢复之Oracle11G R2用exp无法导出空表解决方法

    在11G R2中有个新特性,当表无数据时,不分配segment,以节省空间Oracle当然在执行export导出时,空表则无法导出,但是还是有解决办法的: 解决方法: 一.insert一行,再roll ...

  2. mysql数据库的相关练习题及答案

    表结构示意图: 表结构创建语句: class表创建语句 create table ) not null)engine=innodb default charset=utf8; student表创建语句 ...

  3. windows7系统下让所有文件夹都使用同一种视图的方法

    Windows7系统可以对每个文件夹进行个性化视图设置,可以根据自己的个人喜好和实际需要更改文件或文件夹图标的大小,或者让文件或文件夹以列 表.平铺等方式显示.但是,如果你对N个文件夹视图进行了风格各 ...

  4. windows kibana的连接使用

    下载后解压使用,打开config目录下的kibana.yml文件,然后添加:elasticsearch.url: "http://localhost:9200"  表示你要添加的e ...

  5. Linux 线程实现机制分析 Linux 线程模型的比较:LinuxThreads 和 NPTL

    Linux 线程实现机制分析 Linux 线程实现机制分析  Linux 线程模型的比较:LinuxThreads 和 NPTL http://www.ibm.com/developerworks/c ...

  6. HBase-0.95.1源码分析之split

    split操作执行的是将HBase中较大的Region分为两个.因为split比较耗时,因此split是在独立的线程中完成的,相关类是CompactSplitThread. 首先,CompactSpl ...

  7. 查看crontab的日志记录定位定时任务问题

    1.linux 看 /var/log/cron这个文件就可以,可以用tail -f /var/log/cron观察 2.unix 在 /var/spool/cron/tmp文件中,有croutXXX0 ...

  8. [py]python的私有变量

    参考 python中并没有真正意义上的私有成员,它提供了在成员前面添加双下划线的方法来模拟类似功能.具体来说: _xxx 表示模块级别的私有变量或函数 __xxx 表示类的私有变量或函数 这被称为na ...

  9. java的redis工具类

    package com.mracale.sell.utils; /** * @Auther: Mracale */ import org.springframework.beans.factory.a ...

  10. Git简单入门教程

    1.下载Git,360的软件管家里搜 2.安装Git,下载好之后安装到指定路径下 安装方法有多个复选框的把第一个也选上,其他默认直接next,最后一步什么都不选 3.配置用户信息:(右键-->g ...