hihoCoder[Offer收割]编程练习赛1题目解析
题目1 : 九宫
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描写叙述
小Hi近期在教邻居家的小朋友小学奥数。而近期正好讲述到了三阶幻方这个部分,三阶幻方指的是将1~9不反复的填入一个3*3的矩阵其中,使得每一行、每一列和每一条对角线的和都是同样的。
三阶幻方又被称作九宫格,在小学奥数里有一句很有名的口诀:“二四为肩,六八为足。左三右七。戴九履一。五居当中”。通过这种一句口诀就行很完美的构造出一个九宫格来。
有意思的是,全部的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。如今小Hi准备将一个三阶幻方(不一定是上图中的那个)中的一些数组抹掉,交给邻居家的小朋友来进行还原,而且希望她可以推断出到底是不是仅仅有一组解。
而你呢,也被小Hi交付了相同的任务,可是不同的是。你须要写一个程序~
输入
输入仅包括单组測试数据。
每组測试数据为一个3*3的矩阵。当中为0的部分表示被小Hi抹去的部分。
对于100%的数据。满足给出的矩阵至少能还原出一组可行的三阶幻方。
输出
假设仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包括引號)。
例子输入
0 7 2
0 5 0
0 3 0
例子输出
6 7 2
1 5 9
8 3 4
比較简单的DFS。
AC代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN=10;
int graph[MAXN],vis[MAXN],ans[MAXN];
int flag=0; bool isok()
{
for(int i=1;i<=7;i+=3)
{
if((graph[i]+graph[i+1]+graph[i+2])!=15) return false;
}
for(int i=1;i<=3;i++)
{
if((graph[i]+graph[i+3]+graph[i+6])!=15) return false;
}
if((graph[1]+graph[5]+graph[9])!=15||(graph[3]+graph[5]+graph[7])!=15) return false;
return true;
} void dfs(int pos)
{
if(pos==10&&isok())
{
flag++;
if(flag==1)
{
memcpy(ans,graph,sizeof(graph));
return;
} }
if(graph[pos]) dfs(pos+1);
else
{
for(int i=1;i<=9;i++)
{
if(vis[i]) continue;
vis[i]=1;
graph[pos]=i;
dfs(pos+1);
vis[i]=0;
graph[pos]=0;
}
}
} int main()
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=9;i++)
{
scanf("%d",&graph[i]);
vis[graph[i]]=1;
}
dfs(1);
if(flag==1)
{
for(int i=1;i<=9;i++)
{
printf("%d%c",ans[i],(i%3==0)?'\n':' ');
}
}
else printf("Too Many\n");
}
题目2 : 优化延迟
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描写叙述
小Ho编写了一个处理数据包的程序。程序的输入是一个包括N个数据包的序列。每一个数据包依据其重要程度不同。具有不同的"延迟惩处值"。序列中的第i个数据包的"延迟惩处值"是Pi。
假设N个数据包依照<Pi1, Pi2, ... PiN>的顺序被处理,那么总延迟惩处SP=1*Pi1+2*Pi2+3*Pi3+...+N*PiN(当中i1, i2, ... iN是1, 2, 3, ... N的一个排列)。
小Ho的程序会依次处理每个数据包,这时N个数据包的总延迟惩处值SP为1*P1+2*P2+3*P3+...+i*Pi+...+N*PN。
小Hi希望能够减少总延迟惩处值。他的做法是在小Ho的程序中添加一个大小为K的缓冲区。
N个数据包在被处理前会依次进入缓冲区。当缓冲区满的时候会将当前缓冲区内"延迟惩处值"最大的数据包移出缓冲区并进行处理。直到没有新的数据包进入缓冲区时,缓冲区内剩余的数据包会依照"延迟惩处值"从大到小的顺序被依次移出并进行处理。
比如,当数据包的"延迟惩处值"依次是<5, 3, 1, 2, 4>。缓冲区大小K=2时,数据包被处理的顺序是:<5, 3, 2, 4, 1>。这时SP=1*5+2*3+3*2+4*4+5*1=38。
如今给定输入的数据包序列。以及一个总延迟惩处阈值Q。小Hi想知道假设要SP<=Q。缓冲区的大小最小是多少?
输入
Line 1: N Q
Line 2: P1 P2 ... PN
对于50%的数据: 1 <= N <= 1000。
对于100%的数据: 1 <= N <= 100000, 0 <= Pi <= 1000, 1 <= Q <= 1013。
输出
输出最小的正整数K值能满足SP<=Q。
假设没有符合条件的K,输出-1。
例子输入
5 38
5 3 1 2 4
例子输出
2
用优先队列模拟缓冲区的功能,二分搜索得到最小的缓冲区。
AC代码:
#include<cstdio>
#include<queue>
using namespace std;
const int MAXN=100005;
int P[MAXN],N;
long long Q; bool isOk(int value)
{
long long cnt=0;
int index=1;
priority_queue<int> queue;
for(int i=1;i<=N;i++)
{
if(queue.size()==value)
{
int temp=queue.top();
queue.pop();
cnt+=temp*index++;
}
queue.push(P[i]);
}
while(queue.size())
{
int temp=queue.top();
queue.pop();
cnt+=temp*index++;
}
if(cnt<=Q) return true;
else return false;
} int main()
{
while(scanf("%d%lld",&N,&Q)>0)
{
for(int i=1;i<=N;i++) scanf("%d",&P[i]);
int minn=1;int maxn=100000;
while(minn<=maxn)
{
int mid=(minn+maxn)/2;
if(isOk(mid)) maxn=mid-1;
else minn=mid+1;
}
if(minn>100000) minn=-1;
printf("%d\n",minn);
}
return 0;
}
题目3 : 建造基地
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描写叙述
在遥远的未来。小Hi成为了地球联邦外空间联合开发工作组的一员。前往一颗新发现的星球开发当地的重金属资源。
为了可以在当地生存下来,小Hi首先要建立一个基地。
建立基地的材料可以直接使用当地的石材和富裕的重金属资源。
基地建设分为N级,每一级都须要达成K的建设值后才可以完毕建设。当前级别的建设值溢出后不会影响到下一级的建设。
小Hi能够产出的重金属资源依照精炼程度分为M级,依据开採的数量和精炼的工艺,能够将获取精炼程度为第i级的重金属资源的成本量化为Ai。
在建设第1级基地时,一块精炼度为i的重金属能够提供Bi的建设值,此后基地的级别每提高一级。建设值将除以T并下取整(整除)。
现给定N、M、K、T、A[]和B[]。小Hi须要你帮助他计算他完毕基地建设的最小成本。
输入
输入包括多组測试数据。
输入的第一行为一个整数Q。表示測试数据的组数。
每组測试数据的第一行为4个整数N、M、K和T。意义如前文所述。
接下来的一行为M个整数,分别表示A1~AM。
接下来的一行为M个整数,分别表示B1~BM。
对于100%的数据,满足1<=N<=10,1<=M<=100。1<=K,T<=104。
对于100%的数据,满足Ai和Bi均为32位整型范围内的正整数。
对于100%的数据,满足1<=Q<=10。
输出
对于每组測试数据,假设小Hi终于可以完毕基地建设,则输出小Hi完毕基地建设所须要的最小成本。否则输出“No Answer”。
例子输入
2
2 2 2 2
1 3
1 2
2 2 2 2
1 2
1 1
例子输出
8
No Answer
题意有点绕,想清楚是全然背包问题以后还是比較简单的。
AC代码:
#include<cstdio>
#include<algorithm>
#define INF 1<<30
using namespace std;
typedef long long ll; int main()
{
int Q,N,M,K,T;
int a[110],b[110];
ll dp[10010];
//dp[i]表示价值为i时的最小成本
while(~scanf("%d",&Q))
{
while(Q--)
{
ll res=0;
scanf("%d%d%d%d",&N,&M,&K,&T);
for(int i=1;i<=M;i++) scanf("%d",&a[i]);
for(int i=1;i<=M;i++) scanf("%d",&b[i]);
for(int u=1;u<=N;u++)
{
for(int i=1;i<10010;i++) dp[i]=INF;
dp[0]=0;
for(int i=1;i<=M;i++)
{
for(int j=0;j<=K;j++)
{
if(j+b[i]>K) dp[K]=min(dp[K],dp[j]+a[i]);
else dp[j+b[i]]=min(dp[j+b[i]],dp[j]+a[i]);
}
}
res+=dp[K];
//将每级累加
for(int v=1;v<=M;v++) b[v]/=T;
}
if(res>=INF) puts("No Answer");
else printf("%lld\n",res);
}
}
return 0;
}
题目4 : 舰队游戏
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描写叙述
小Hi近期在玩一款组建舰队出海进行战争的游戏,在这个游戏中,小Hi须要依据须要组建一仅仅舰队。一支舰队里最多同一时候存在N艘舰船。每艘舰船最多同一时候装备M个装备。
在一次关卡中,小Hi希望可以组建一仅仅仅由航母构成的舰队,这意味着全部舰船的装备都是某种类型的飞机,小Hi将要使用的飞机有两种类型:对空飞机和对舰飞机,顾名思义,对空飞机用于和敌对舰船搭载的飞机进行对抗,而对舰飞机则直接用于攻击敌对舰船本身。
每艘航母的M个装备栏位是不一样的,我们能够用“搭载量”来对其进行量化描写叙述,有些装备栏位的搭载量较高。有些装备栏位的搭载量较低,对于第i艘舰船,我们用Ai,j表示其第j个装备栏位的搭载量。
小Hi的军备库里有T架飞机。我们Bi表示第i架飞机的对空攻击力,并用Ci表示第i架飞机的对舰攻击力,当中对空飞机的对舰攻击力为0,对舰飞机的对空攻击力为0。
为舰船装备飞机,会提高舰队的“制空值”和“伤害值”。
舰队的制空值为全部飞机的对空攻击力与其相应的装备栏位的搭载量的乘积之和,即:
制空值=
当中pi,j表示放置在第i艘舰船的第j个装备栏位的飞机编号。同理,舰队的伤害值为全部飞机的对舰攻击力与其相应的装备栏位的搭载量的乘积之和,即
伤害值=
为了可以顺利的通过关卡,小Hi须要使得舰队的制空值不低于一个给定的值S,而且希望在这个条件下舰队的伤害值越高越好,这样可以尽量降低舰队的损耗。
同一时候,因为一艘舰船至少要装备一架对舰飞机才可以在炮击战中发动攻击。所以小Hi也好奇是否存在在满足制空值限制且伤害值最高的情况下,同一时候满足每一艘舰船至少装备一架对舰飞机。
而这个问题。就有待你来进行计算了~
输入
输入第一行为一个正整数Q。表示測试数据的组数。
在每组測试数据的第一行,为4个正整数N、M、T和S。意义如之前所述。
第2行~第n+1行,每行m个正整数。相应矩阵A。
第n+2行,为T个正整数B1 .. BT。
第n+3行,为T个正整数C1 .. CT。
对于30%的数据。满足N<=2,M<=2,T<=20,Q<=100。
对于剩下70%的数据,满足N<=4。M<=4,T<=1000。Q<=3。
对于100%的数据,满足1<=Ai,j, Bi, Ci <= 1000。0<= S <= 108。
输出
对于每组測试数据,假设存在满足制空值限制的方案的话,则首先在第一行输出在满足制空值限制下可以达到的最大攻击力D,在第二行中。假设在满足制空值限制且伤害值最高的情况下。可以同一时候满足每一艘舰船至少装备一架对舰飞机,则输出Yes,否则输出No。
假设不存在满足制空值限制的方案的话。则输出一行Not Exist。
例子输入
3
1 2 1 38
4 5
0
5
1 2 8 7
1 4
0 3 2 0 0 2 0 0
5 0 0 3 3 0 3 4
2 1 4 29
5
3
0 4 3 0
1 0 0 3
例子输出
Not Exist
5
Yes
0
No
对值直接从小到大排序,然后就是枚举状态贪心计算。
AC代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const MAX=1e3+5;
int N,M,T,S;
int sz_a;
int sz_b;
//对空飞机的数量
int sz_c;
//对舰飞机的数量
int b[MAX],B[MAX],c[MAX],C[MAX];
struct A
{
int num,pos;
}a[5][5],temp[20]; bool cmp(A x,A y)
{
return x.num>y.num;
} //计算对空值
int cal_air(int k)
{
memset(temp,0,sizeof(temp));
sz_a=0;
//搭载了多少架对空飞机
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
if(k&(1<<(i*M+j)))
{
temp[sz_a++].num=a[i][j].num;
}
}
}
sort(temp,temp+sz_a,cmp);
int res=0;
for(int i=0,j=0;i<sz_a&&j<sz_b;i++,j++) res+=temp[i].num*B[j];
return res;
} //计算对舰值
int cal_ship(int k)
{
memset(temp,0,sizeof(temp));
sz_a=0;
//搭载了多少架对舰飞机
for(int i=0;i<N&&sz_a<=sz_c;i++)
{
for(int j=0;j<M&&sz_a<=sz_c;j++)
{
if(!(k&(1<<(i*M+j))))
//假设已经搭载了对空飞机就不能搭载对舰飞机
{
temp[sz_a].num=a[i][j].num;
temp[sz_a++].pos=a[i][j].pos;
//后面还要用到舰艇的信息
}
}
}
sort(temp,temp+sz_a,cmp);
int res=0;
for(int i=0,j=0;i<sz_a&&j<sz_c;i++,j++) res+=temp[i].num*C[j];
return res;
} //计算能不能满足每一艘舰船至少装备一架对舰飞机
bool judge_ship()
{
//枚举每一艘舰艇
for(int i=0;i<N;i++)
{
bool flag=false;
for(int j=0;j<M&&!flag;j++)
{
for(int k=0;k<min(sz_a,sz_c)&&!flag;k++)
{
if(((1<<(i*M+j))&temp[k].pos)) flag=true;
}
}
if(!flag) return false;
}
return true;
} int main()
{
int Q;
scanf("%d",&Q);
while(Q--)
{
sz_b=0;
sz_c=0;
scanf("%d%d%d%d",&N,&M,&T,&S);
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
scanf("%d",&a[i][j].num);
a[i][j].pos=(1<<(i*M+j));
}
}
for(int i=0;i<T;i++)
{
scanf("%d",&b[i]);
if(b[i]) B[sz_b++]=b[i];
}
for(int i=0;i<T;i++)
{
scanf("%d",&c[i]);
if(c[i]) C[sz_c++]=c[i];
}
sort(B,B+sz_b,greater<int>());
sort(C,C+sz_c,greater<int>());
int ans=-1,tot=1<<(N*M);
// N艘舰船,每艘舰船M个装备,每一个装备有装载和未装载两种情况,一共枚举2*n*m种可能
bool has=false;
for(int i=0;i<tot;i++)
{
if(cal_air(i)>=S)
{
int temp=cal_ship(i);
if(temp>ans||(temp==ans&&!has))
{
ans=temp;
has=judge_ship();
}
}
}
if(ans==-1) printf("Not Exist\n");
else printf("%d\n%s\n",ans,has?"Yes":"No");
}
}
hihoCoder[Offer收割]编程练习赛1题目解析的更多相关文章
- hihocoder [Offer收割]编程练习赛4
描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...
- hihocoder [Offer收割]编程练习赛61
[Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...
- ACM学习历程—Hihocoder [Offer收割]编程练习赛1
比赛链接:http://hihocoder.com/contest/hihointerview3/problem/1 大概有一个月没怎么打算法了.这一场的前一场BC,也打的不是很好.本来Div1的A和 ...
- hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)
题目链接:http://hihocoder.com/problemset/problem/1532 题解:一道基础的dp,设dp[i][j][k][l]表示处理到第几个数,当前是哪个和弦错了几次初始x ...
- hihocoder [Offer收割]编程练习赛52 D 部门聚会
看了题目的讨论才会做的 首先一点,算每条边(u, v)对于n*(n+1)/2种[l, r]组合的贡献 正着算不如反着算 哪些[l, r]的组合没有包含这条边(u, v)呢 这个很好算 只需要统计u这半 ...
- hihocoder [Offer收割]编程练习赛14
A.小Hi和小Ho的礼物 谜之第1题,明明是第1题AC率比C还要低.题目是求在n个不同重量袋子选4袋,2袋给A,2袋给B,使2人获得重量相同,求问方案数. 我也是一脸懵b...o(n2)暴力枚举发现把 ...
- hihocoder [Offer收割]编程练习赛14 剑刃风暴
题目4 : 剑刃风暴 时间限制:20000ms 单点时限:2000ms 内存限制:256MB 描述 主宰尤涅若拥有一招非常厉害的招式——剑刃风暴,“无论是战士还是法师,都害怕尤涅若的武士刀剑技”. 现 ...
- hihocoder [Offer收割]编程练习赛14 可疑的记录
题目3 : 可疑的记录 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi有一棵N个节点的树,编号1-N,其中1号节点是整棵树的根.他把这棵树的N-1条边记录成N-1 ...
- hihocoder [Offer收割]编程练习赛14 投掷硬币
题目2 : 投掷硬币 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi有一枚神奇的硬币.已知第i次投掷这枚硬币时,正面向上的概率是Pi. 现在小Hi想知道如果总共投 ...
随机推荐
- 统计个位数的数目 Exercise07_07
/** * @author 冰樱梦 * 时间:2018年下半年 * 题目:统计个位数的数目 * */ public class Exercise07_07 { public static void m ...
- [HTML/CSS]说说position
目录 语法 作用 使用定位的条件 总结 语法 position : static absolute relative(static.absolute.relative常用值). 参数 static : ...
- JS的scrollIntoView学习
scrollIntoView(alignWithTop) 滚动浏览器窗口或容器元素,以便在当前视窗的可见范围看见当前元素.如果alignWithTop为true,或者省略它,窗口会尽可能滚动到自身顶 ...
- webpack与browser-sync热更新原理深度讲解
本文首发于CSDN网站,下面的版本又经过进一步的修订.原文:webpack与browser-sync热更新原理深度讲解本文包含如下内容: webpack-hot-middleware EventSou ...
- JavaScript基础入门教程(四)
说明 前面三篇博客介绍了js中基本的知识点,包括变量类型及其转换.表达式.运算符等小知识点,这篇博客主要讲的是对象.如果你学过java等语言,你也许在下文的阅读中发现在js中的对象与java中的对象存 ...
- pycharm的插件pylint报错:java.lang.Throwable: Write-unsafe context! Model changes are allowed from write-safe contexts only. Please ensure you're using invokeLater/invokeAndWait with a correct modality stat
java.lang.Throwable: Write-unsafe context! Model changes are allowed from write-safe contexts only. ...
- springCloud微服务使用
一.微服务简介 1.演变过程:单体架构.SOA.微服务 2.单体架构:一个应用包含了应用之间所有的功能程序,通过打成war包的方式发布部署. 缺点:复杂性逐渐偏高.技术债务逐渐变慢.阻碍技术的创新扩展 ...
- Android双系统实现
1. 前言: 刷机,似乎是安卓手机用户的一项专利,可是,会刷机的用户一般都是喜新厌旧的角色. 一个系统用久了.就想换到还有一个系统.或者认为没有原来的好,或者又认为要换回去.这样又要重刷. 可是刷来刷 ...
- [转] SQL SERVER拼接字符串(字符串中有变量)
本文转自:http://blog.csdn.net/sikaiyuan2008/article/details/7848926 SQL SERVER拼接字符串(字符串中有变量)对我来说是一个难点,总是 ...
- iOS:触摸事件和手势识别的介绍
触摸事件和手势识别的介绍 1.iOS的输入事件 UIKit可识别三种类型的输入事件: 触摸事件 运动事件 远程控制事件 iOS中许多事件对象都是UIEvent类的实例,UIEvent记录了事件所产生 ...