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. kmp跑两串的最大相同前后缀 HDU2594

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=2594 如题. 思路: Next数组记录的是pos位置失配时要跑到哪里,所以最后得再添加一个字符‘#’. 连 ...

  2. Photon Server 实现注册与登录(二) --- 服务端代码整理

    一.有的代码前端和后端都会用到.比如一些请求的Code.使用需要新建项目存放公共代码. 新建项目Common存放公共代码: EventCode :存放服务端自动发送信息给客户端的code Operat ...

  3. POJ 1860 汇率 SPFA

    题意 有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 ...

  4. 【php设计模式】观察者模式

    当对象间存在一对多关系时,则使用观察者模式.比如,当一个对象被修改时,则会自动通知它的依赖对象.观察者模式属于行为型模式. <?php class Subject{ private $obser ...

  5. angularJs同步请求

    今天在写几级联动的时候,因为比如上一个接口请求数据成功返回后,才能根据上一个接口返回的数据请求下一个接口,以此类推:因此有了同步请求的想法. 在前端做同步读取显然不是好的实践做法,同步之后会严重影响前 ...

  6. c#向指定的邮箱发送邮件

    private bool SendEmail(string fileName) { MailMessage m_Mail = new MailMessage(); m_Mail.From = new ...

  7. ZPL语言完成条形码的打印

    近期因为项目的需求,需要使用到打印机来打印业务相关的条形码和其他信息,由于之前有操作其它打印机的经验,Leader就安排我来做这个了(凑哦,这能说我是懵逼的么).于是就开始了我的探索之旅啦,不对,是踩 ...

  8. VIM从原理上认识^M问题

    问题背景 VIM在打开文件的时候如果遇到两种换行符风格(dos与unix)共存的文件,通常会在行尾显示出烦人的^M.如果^M较少,比较容易定位到哪几行出了问题,但是如果^M较多,就很难搞.下面先给出解 ...

  9. Notepad++快捷键及使用技巧

    常用快捷键: CTRL+Q 注释/取消注释 用Notepad++写代码,要是有一些重复的代码想copy一下,还真不容易,又得动用鼠标,巨烦人....有木有简单的方法呢,确实还是有的不过也不算太好用.主 ...

  10. 前端基础(八):Font Awesome(图标)

    一.font awesome简介 目前图标总数共有519个; 不依赖Javascript 矢量图形,无限缩放 免费,可用于商业 CSS控制样式,自定义图标颜色,大小,阴影,一切可能实现的效果 支持re ...