T1神奇的幻方

直通

思路:

  制定一个lrow记录上一个数字所在的行数,lcolume记录上一个数字所在的列数,然后根据题目的描述进行更改即可

上代码:

#include <iostream>
#include <cstdio>
using namespace std; const int Maxn = ;
int n,a[Maxn][Maxn]; int main() {
scanf("%d",&n);
int mid=n/+,Max=n*n;
int lrow=,lcolume=mid;
a[lrow][lcolume]=;
for(int i=; i<=Max; ++i) {
if(lrow== && lcolume!=n)
lrow=n,a[lrow][++lcolume]=i;
else if(lrow!= && lcolume==n)
lcolume=,a[--lrow][lcolume]=i;
else if(lrow== && lcolume==n)
a[++lrow][lcolume]=i;
else if(lrow!= && lcolume!=n) {
if(a[lrow-][lcolume+]==)
a[--lrow][++lcolume]=i;
else
a[++lrow][lcolume]=i;
}
}
for(int i=; i<=n; ++i) {
for(int j=; j<=n; ++j)
printf("%d ",a[i][j]);
printf("\n");
}
return ;
}

T2 信息传递

直通

思路:

  讲真这道题是有各种各样的作法...这里给出的是拓扑排序+dfs

上代码:

#include <iostream>
#include <cstdio> using namespace std; const int M = 2e5 + ;
int n,minn=0x7fffffff;
int t[M],ru[M];
bool v[M]; void topo(int i)
{
int v=t[i];
t[i]=;
ru[v]--;
if(!ru[v]) topo(v);
} void dfs(int x,int steps)
{
if(v[x])///环完成
{
if(steps<minn) minn=steps;///更新
return;
}
v[x]=true;
dfs(t[x],steps+);
return;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&t[i]);
ru[t[i]]++;
}
for(int i=;i<=n;i++)
if(!ru[i]) topo(i);
for(int i=;i<=n;i++)
if(ru[i] && !v[i]) dfs(i,);
printf("%d",minn);
return ;
}

T3 斗地主

直通

数据保证:所有的手牌都是随机生成的。

思路:

  首先说在前面,这题有好几种解法....

  什么bfs啊,什么dfs+贪心啊,什么dp啊.

  然而我只会dfs+贪心以及dp版的,但是由于懒嘛,就只写dp版的啦~

  具体完整版请出门右拐通往gaoji大佬的博客园:www.cnblogs.com/zwfymqz/

  搜索斗地主:你会看到你想要的

坑点:

  如上大红字,这就是为什么贪心差不多可以过的原因了吧~

    在做题的时候一定要将循环里的变量搞清楚!这次吃了大亏了...qwq

上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath> using namespace std; const int M = ;
int T,n,ans;
///手牌的组数,每组手牌的张数,记录的答案
int dp[M][M][M][M];
///dp[i][j][k][l]表示打出i套四张,j套三张,k套两张,l张单牌所需要的最少步数
int cnum[M],happens[M/];
int num[]={,,,}; int calc(int one,int two,int three,int four,int king)
{
if(king==)///只出现一张大小王
{
one++; ///当作一张单牌
king--; ///清空
}
if(king==) ///当做一张单牌来用
return dp[four][three][two][one];
else
//return min(dp[four][three][two][one+2],dp[four][three][two+1][one]);
return min(dp[four][three][two][one+],dp[four][three][two][one]+);
///当做2张单牌,或者当做一对对牌
} void dfs(int now) ///now是指已经操作的次数
{
if(now>=ans) ///最优性剪枝,这个重要
return;
memset(happens,,sizeof(happens));///清空
for(int i=;i<=;i++)
happens[cnum[i]]++; ///记录出现几次的牌有几种
ans=min(ans,now+calc(happens[],happens[],happens[],happens[],cnum[]));
for(int k=;k<=;k++) ///k表示几顺子
{
for(int i=;i<=;i++)
{
int j;
for(j=i;j<= && cnum[j]>=k;j++)///若可能组成k顺子
{
cnum[j]-=k; ///耗费掉了
if(j-i+>=num[k])
dfs(now+); ///组成k顺子成功!!!
}
for(j--;j>=i;j--)
cnum[j]+=k; ///回溯
}
}
} int main()
{
scanf("%d%d",&T,&n);
memset(dp,,sizeof(dp));
///上面那个其实没什么用...可有可无
dp[][][][]=;
///当每张都不打出去的时候,步数为0
for(int i=;i<=n;i++) ///four
for(int j=;j<=n;j++) ///three
for(int k=;k<=n;k++) ///two
for(int l=;l<=n;l++) ///one
if(i*+j*+k*+l<=n) ///在范围之内
{
///赋值为最坏情况:当每张牌都一张一张的打出去
///故将dp数组memset大概是没什么用的
dp[i][j][k][l]=i+j+k+l;
if(i)
{
///将4张牌进行分解
///(3+1) || (2+2)
dp[i][j][k][l]=min(dp[i][j][k][l],min(dp[i-][j+][k][l+],dp[i-][j][k+][l]));
///(2+1+1) || (1+1+1+1)
dp[i][j][k][l]=min(dp[i][j][k][l],min(dp[i-][j][k+][l+],dp[i-][j][k][l+]));
if(k>=)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k-][l]+),
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k-][l]+);
///四带一对对牌(一个对牌)
if(l>=)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k][l-]+);
///四带一对单牌(2张单牌)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k][l]+);
///什么都不带
}
if(j)
{
///将3张牌进行分解
///(2+1) || (1+1+1)
dp[i][j][k][l]=min(dp[i][j][k][l],min(dp[i][j-][k+][l+],dp[i][j-][k][l+]));
if(k)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j-][k-][l]+);
///三带一对
if(l)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j-][k][l-]+);
///三带一
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j-][k][l]+);
///什么都不带
}
if(k)
{
///将2张牌进行分解
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j][k-][l+]);
///一对牌
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j][k-][l]+);
}
if(l)///一张单牌
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j][k][l-]+);
}
while(T--)
{
memset(cnum,,sizeof(cnum));
///多组数据
ans=n;
///最差情况
int ai,meiyong;
for(int i=;i<=n;i++)
{ ///读入数码,以及花色(讲真没啥用)
scanf("%d%d",&ai,&meiyong);
if(ai==)
cnum[]++;
///储存A(尖?),把A转化为14数码
else
cnum[ai]++;
///其他的按原来数码进行储存(大小王也一样~)
}
dfs();
printf("%d\n",ans);
}
return ;
}

Noip2015 提高组 Day1的更多相关文章

  1. noip2015 提高组day1、day2

    NOIP201505神奇的幻方   试题描述 幻方是一种很神奇的N∗N矩阵:它由数字 1,2,3,……,N∗N构成,且每行.每列及两条对角线上的数字之和都相同.    当N为奇数时,我们可以通过以下方 ...

  2. NOIP2015提高组Day1 Message

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

  3. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  4. luogu1003铺地毯[noip2011 提高组 Day1 T1]

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  5. [NOIP2015] 提高组 洛谷P2615 神奇的幻方

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  6. 洛谷-神奇的幻方-NOIP2015提高组复赛

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  7. 洛谷 P2678 & [NOIP2015提高组] 跳石头

    题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...

  8. 【数据结构】运输计划 NOIP2015提高组D2T3

    [数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...

  9. 【二分查找】 跳石头NOIP2015提高组 D2T1

    [二分查找]跳石头NOIP2015提高组 D2T1 >>>>题目 [题目描述] 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石 ...

随机推荐

  1. opencv实现人脸识别(四) 人脸识别模块

    到这一步就是进行人脸识别了. 流程图: 代码: import cv2 def recognize(cam): recognizer = cv2.face.LBPHFaceRecognizer_crea ...

  2. 关于python中的包,模块导入的问题详解(一)

    最近由于初学python,对包,模块的导入问题进行了资料的搜集,查阅,在这里做一个总结: 一: import 模块 在import的过程中发生了什么?我们用一个实验来说明: 以上截图表明:在impor ...

  3. python — lambda表达式与内置函数

    目录 1 lambda表达式 (匿名函数) 2 内置函数 1 lambda表达式 (匿名函数) 用于表示简单的函数 lambda表达式,为了解决简单函数的情况: def func(a1,a2): == ...

  4. ES6用来判断数值的相关函数

    最近在学习ES6的基础知识,整理了一下ES6用来判断数值的相关函数 Math.sign() =>判断正负数的函数 Math.trunc() =>取整函数 Number.isInteger( ...

  5. MongoDB查询操作 返回指定字段(C#官方驱动)

    首先,MongoDB中返回指定的字段的查询方法如下: db.person.find({Name:"小丑"},{Age:1,Sex:1}) 该语句表示:查询person表中name为 ...

  6. 1.DOS常用命令

    d:+ 回车:盘符切换,进入D:盘 dir(directory):列出当前目录下的文件及文件夹md(make director):创建目录rd(remove director):删除目录(不能删除非空 ...

  7. ubuntu 一键搭建VNN

    #!/bin/bash if [ $(id -u) != "0" ]; then printf "Error: You must be root to run this ...

  8. python中的% 是什么意思, 起到什么作用?

    %Y会被无世纪的年份所替代.%m会被01到12之间的一个十进制月份数替代,其他依次类推. 1.%在python的格式化输出,有转换字符的飞鲸作用: (1)%c 整数转成对应的 ASCII 字元: (2 ...

  9. git 常用命令操作

    目录 一.用户和邮箱 用户和邮箱的作用 查看用户名和邮箱地址 修改用户名和邮箱地址 用户名和邮箱地址的作用 用户名和邮箱地址是本地git客户端的一个变量,不随git库而改变. 每次commit都会用用 ...

  10. Linux部署tomcat服务常用命令

    cd / 转到根目录 ps -ef|grep tomcat查看进程 ./bin/shutdown.sh 关闭 rm -r logs/* 清除日志 ps -ef|grep tomcat查看进程 ./bi ...