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 >>>>题目 [题目描述] 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石 ...
随机推荐
- MGR+Consul集群
[root@mydb1 ~]# wget https://releases.hashicorp.com/consul/1.4.0/consul_1.4.0_linux_amd64.zip[root@m ...
- poj 1006中国剩余定理模板
中国剩余定理(CRT)的表述如下 设正整数两两互素,则同余方程组 有整数解.并且在模下的解是唯一的,解为 其中,而为模的逆元. 模板: int crt(int a[],int m[],int n) { ...
- HTTP协议探究(二):代理、网关和隧道
一 复习与目标 1 复习 缓存目的:减轻服务器压力,不重复请求相同的内容 缓存位置:浏览器或中间代理 相关状态码:200或403 相关首部: etag和since-none-match.last-mo ...
- Zookeeper 入门详解
zookeeper zookeeper是什么 Apache ZooKeeper是Apache软件基金会的一个软件项目,他为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册.ZooKeeper ...
- css的一些样式
input标签中的一些样式: <input type="text">:表示输入文本 <input type="password">:表示 ...
- SpringBoot实现定时器定时处理任务
最近在项目中遇到了一个问题, 对于新建的活动, 活动设置了开始时间和结束时间, 也就是数据库中的一个状态码的改变而已. 但是,这里就有问题了, 如何去实现到时间更改活动状态呢? 1. 刚开始的时候,我 ...
- hbulider 快捷键
跳转到行 Ctrl + G 页首 Ctrl + Home 页尾 Ctrl + End 下一个选项卡 Ctrl + Tab 上一个 ...
- printf颜色
格式 printf("\033[?m%s\033[0m", str); 多个属性以:分隔 属性: \033[0m:关闭所有属性 \033[1m:设置高亮度 \033[4m:下划线 ...
- chrome浏览器重新安装不了
1.打开注册表方法1. windows键 + R-->输入regedit-->回车方法2.开始-运行里输入regedit方法3.单击任务栏中windows图标,在搜索程序和文件中输入reg ...
- django中app_name以及namespace理解
在写django的时候,html中反向解析经常会用到app_name 但有时候又是namespace,具体的区别如下: 大部分情况 这两者有其一就可以了. 并且两者(可以简化理解)无区别 只要一种情况 ...