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

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. php之setcookie

    注意在任何发送请求头之前不能有输出,不然会获取不到header头 setcookie(key,value, expires, 'path', domain); 在发送cookie时,会自动把cooki ...

  2. table 的td 自适应事项

    media的html结构,如果用display:table-cell实现, table { width: 100%; border-collapse: collapse; border: $bor; ...

  3. IO流(6)获取功能

    获取功能: * public String getAbsolutePath():获取绝对路径 * public String getPath():获取相对路径 * public String getN ...

  4. xss跨站脚本攻击及xss漏洞防范

    xss跨站脚本攻击(Cross Site Scripting,因与css样式表相似故缩写为XSS).恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Scrip ...

  5. PAT 1023 Have Fun with Numbers[大数乘法][一般]

    1023 Have Fun with Numbers (20)(20 分) Notice that the number 123456789 is a 9-digit number consistin ...

  6. 浅谈远程登录时,ssh的加密原理

    SSH:Secure Shell,是一种网络安全协议,主要用于登录远程计算机的加密过程. 登录方式主要有两种: 1.基于用户密码的登录方式:   加密原理:   当服务器知道用户请求登录时,服务器会把 ...

  7. Improving the quality of the output

    There are a variety of reasons you might not get good quality output from Tesseract. It's important ...

  8. 使用Fiddler手机抓包https-----重要

    Fiddler不仅可以对手机进行抓包,还可以抓取别的电脑的请求包,今天就想讲一讲使用Fiddler手机抓包! 使用Fiddler手机抓包有两个条件: 一:手机连的网络或WiFi必须和电脑(使用fidd ...

  9. php unset()函数销毁变量但没有实现内存释放

    <?PHP $a = "hello";$b = &$a;unset( $b );echo $a; // 输出 helloecho $b; // 报错$b = &quo ...

  10. javascript函数定义以及常见用法

                  我们知道,js函数有多种写法,函数声明 ,函数表达式,Function式构造函数,自执行函数,包括Es6的箭头函数,Class类写法,高阶函数,函数节流/函数防抖,下面我就 ...