Noip2015 提高组 Day1
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的更多相关文章
- noip2015 提高组day1、day2
NOIP201505神奇的幻方 试题描述 幻方是一种很神奇的N∗N矩阵:它由数字 1,2,3,……,N∗N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方 ...
- NOIP2015提高组Day1 Message
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 【题解】NOIP2015提高组 复赛
[题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...
- luogu1003铺地毯[noip2011 提高组 Day1 T1]
题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...
- [NOIP2015] 提高组 洛谷P2615 神奇的幻方
题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...
- 洛谷-神奇的幻方-NOIP2015提高组复赛
题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...
- 洛谷 P2678 & [NOIP2015提高组] 跳石头
题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...
- 【数据结构】运输计划 NOIP2015提高组D2T3
[数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...
- 【二分查找】 跳石头NOIP2015提高组 D2T1
[二分查找]跳石头NOIP2015提高组 D2T1 >>>>题目 [题目描述] 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石 ...
随机推荐
- kmp跑两串的最大相同前后缀 HDU2594
题意:http://acm.hdu.edu.cn/showproblem.php?pid=2594 如题. 思路: Next数组记录的是pos位置失配时要跑到哪里,所以最后得再添加一个字符‘#’. 连 ...
- Photon Server 实现注册与登录(二) --- 服务端代码整理
一.有的代码前端和后端都会用到.比如一些请求的Code.使用需要新建项目存放公共代码. 新建项目Common存放公共代码: EventCode :存放服务端自动发送信息给客户端的code Operat ...
- POJ 1860 汇率 SPFA
题意 有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 ...
- 【php设计模式】观察者模式
当对象间存在一对多关系时,则使用观察者模式.比如,当一个对象被修改时,则会自动通知它的依赖对象.观察者模式属于行为型模式. <?php class Subject{ private $obser ...
- angularJs同步请求
今天在写几级联动的时候,因为比如上一个接口请求数据成功返回后,才能根据上一个接口返回的数据请求下一个接口,以此类推:因此有了同步请求的想法. 在前端做同步读取显然不是好的实践做法,同步之后会严重影响前 ...
- c#向指定的邮箱发送邮件
private bool SendEmail(string fileName) { MailMessage m_Mail = new MailMessage(); m_Mail.From = new ...
- ZPL语言完成条形码的打印
近期因为项目的需求,需要使用到打印机来打印业务相关的条形码和其他信息,由于之前有操作其它打印机的经验,Leader就安排我来做这个了(凑哦,这能说我是懵逼的么).于是就开始了我的探索之旅啦,不对,是踩 ...
- VIM从原理上认识^M问题
问题背景 VIM在打开文件的时候如果遇到两种换行符风格(dos与unix)共存的文件,通常会在行尾显示出烦人的^M.如果^M较少,比较容易定位到哪几行出了问题,但是如果^M较多,就很难搞.下面先给出解 ...
- Notepad++快捷键及使用技巧
常用快捷键: CTRL+Q 注释/取消注释 用Notepad++写代码,要是有一些重复的代码想copy一下,还真不容易,又得动用鼠标,巨烦人....有木有简单的方法呢,确实还是有的不过也不算太好用.主 ...
- 前端基础(八):Font Awesome(图标)
一.font awesome简介 目前图标总数共有519个; 不依赖Javascript 矢量图形,无限缩放 免费,可用于商业 CSS控制样式,自定义图标颜色,大小,阴影,一切可能实现的效果 支持re ...