A题:小B准备出模拟赛。
她把题目按难度分为四等,分值分别为6,7,8,9。
已知小B共出了m道题,共n分。
求小B最少出了多少道6分题。
题解:由题意可知若有解,首先要符合 6m<=n<=9m。假设有x道6分题,那么有 7(m-x)<=n-6x<=9(m-x)。
移项可得 7m-n<=x<=(9m-n)/3 即最小的符合条件的就为7m-n.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m;
int main()
{
scanf("%lld %lld",&n,&m);
if(6*m>n||n>9*m){
printf("jgzjgzjgz\n");
}
else {
ll ans=max(0ll,7*m-n);
printf("%lld\n",ans);
}
return 0;
}
B题:小j开始打工,准备赚钱买煤气灶。
第一天,小j的工资为n元,之后每天他的工资都比前一天多d元。
已知煤气灶需要m元,求小j最少工作几天才能买到煤气灶。
题解:明显是个等差数列求和,因为x值很大,所以需要二分一下。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,d,x;
bool check(ll k)
{
ll t=1ll*(k*n+k*(k-1)/2*d);
if(t>=m){
return true;
}
else return false;
}
int main()
{
scanf("%lld %lld %lld %lld",&n,&m,&d,&x);
ll l=1,r=x;
while(l<r){
ll mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%lld\n",l);
return 0;
}
C题:小B想给她的新项链染色。
现在有m种颜色,对于第i种颜色,小B有a_i单位的颜料,每单位颜料可以染项链的一个珠子;
同时,小B对于第i种颜色的喜爱度为b_i。
已知项链有n个珠子,求染色后每个珠子的颜色的喜爱度之和的最大值。
(每个珠子只能至多被染一次,不被染色则喜爱度为0)
题解:按照喜爱度排序,简单贪心一下即可。
代码:
#include <bits/stdc++.h>
using namespace std;
int n,m;
typedef long long ll;
struct Color{
int a,b;
bool operator <(const Color &k)const
{
return b>k.b;
}
};
struct Color c[100010];
int main()
{
ll ans=0;
int cnt=0;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d",&c[i].a);
}
for(int i=1;i<=m;i++){
scanf("%d",&c[i].b);
}
sort(c+1,c+m+1);
for (int i=1;i<=m;i++){
if(cnt>=n) break;
if(cnt+c[i].a>=n){
if(c[i].a>=n-cnt){
ans+=(n-cnt)*c[i].b;
cnt=n;
}
else {
ans+=c[i].a*c[i].b;
cnt+=c[i].a;
}
}
else{
ans+=c[i].a*c[i].b;
cnt+=c[i].a;
}
}
printf("%lld\n",ans);
return 0;
}
D题:小B喜欢美食。
现在有n个美食排成一排摆在小B的面前,依次编号为1..n,编号为i的食物大小为 a[i] ,即足够小B吃 a[i] 口。
小B每次会吃两口,这两口要么是编号相同的美食,要么是编号之差的绝对值为1的美食。
小B想知道,她最多能吃几次?
题解:分析可知无论是先把同编号的取完,还是和相邻位的取完,两个加起来都是一样的,所有可以把每一位都除以2再加起来。就是还要判断一下如果当前位为1,如果下一位不为0,那么答案加上1,下一位减1.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100010];
ll n;
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
ll ans=0;
for(int i=1;i<=n;i++){
if(a[i]==1&&a[i+1]!=0){
ans+=1;a[i+1]--;
continue ;
}
if(a[i]%2!=0&&a[i]!=1){
ans+=a[i]/2;
if(a[i+1]!=0){
ans++;
a[i+1]--;
}
continue ;
}
if(a[i]%2==0){
ans+=a[i]/2;
continue ;
}
}
printf("%lld\n",ans);
return 0;
}
E题:有一个沿海地区,可以看作有n行m列的城市,第i行第j列的城市海拔为h[i][j]。
由于沿海,所以这个地区经常会发生海啸。
海啸发生时,部分城市会被淹没,具体来说,海水高度会达到d,因此海拔低于d的城市都会被淹没。
现在有q次询问,每次问你一个矩形区域中,有多少城市不会被淹没。
题解:简单的二维前缀和,就是数组的创建需要点技巧。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//vector <ll> h[10];
ll *h[1000010];
ll d;
int q,n,m,a,b,x,y;
int main()
{
scanf("%d %d %lld",&n,&m,&d);
for(int i=0;i<=n;i++) h[i]=new ll [m+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
h[i][j]=0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
ll t;
scanf("%lld",&t);
if(t>=d){
h[i][j]=1;
}
else h[i][j]=0;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
h[i][j]+=h[i-1][j]+h[i][j-1]-h[i-1][j-1];
}
}
scanf("%d",&q);
ll ans=0;
while (q--){
scanf("%d %d %d %d",&a,&b,&x,&y);
ans=h[x][y]-h[a-1][y]-h[x][b-1]+h[a-1][b-1];
printf("%lld\n",ans);
}
return 0;
}
G题:
求a|(a+1)|(a+2)|...|(b-1)|b。
其中|表示[按位或](https://baike.baidu.com/item/%E6%8C%89%E4%BD%8D%E6%88%96)。
题解:不懂解释,还是直接上官方解释吧。
考虑a和b的二进制表示从高到低第一个不同的位i,
必定b的第i位=1,a的第i位=0。
那么可以断定,对于答案的二进制表示,
(1) 比第i位更高的那些位一定跟a相同。
(2) 第i位及比第i位更低的那些位一定为1。
(1)是显然的,(2)是由于把a中比第i位更低的那些位都置为1得到的数一定在区间[a,b]中。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b;
int main()
{
while(scanf("%lld %lld",&a,&b)!=EOF){
ll x=1;
ll t=a^b;
while (t>=x) x*=2;
printf("%lld\n",a|b|(x-1));
}
return 0;
}
J题:你在一个 n 行 m 列的网格迷宫中,迷宫的每一格要么为空,要么有一个障碍。
你当前在第 r 行第 c 列(保证该格子为空)。每次移动你可以向上下左右任意一个方向移动一格,前提是不能走到障碍上,也不能超出迷宫的边界。
你向左移动的次数不能超过 x 次,向右不能超过 y 次。
问在这种情况下,对于每个格子,是否存在一种移动方案让你走到它。
输出有多少个格子存在移动方案让你走到它。
题解:看不太懂题解是啥,感觉是我没理解对题目吗.......就写了个bfs模拟题意 水了过去
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
char maps[1010][1010];
int r,c,x,y;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct pos
{
int xx,yy;
int cx,cy;
};
void bfs(int X,int Y)
{
queue<pos> q;
struct pos t;
t.xx=X,t.yy=Y;
t.cx=0,t.cy=0;
q.push(t);
maps[X][Y]='+';
while(!q.empty()){
struct pos now,next;
now=q.front();
q.pop();
for(int i=0;i<4;i++){
if(now.cx>=x&&i==3) continue;
if(now.cy>=y&&i==2) continue;
int tx=dir[i][1]+now.xx;
int ty=dir[i][0]+now.yy;
if(tx<0||tx>=n||ty<0||ty>=m||maps[tx][ty]=='*'||maps[tx][ty]=='+') continue ;
maps[tx][ty]='+';
if(i==2){
next.cy=now.cy+1;
next.cx=now.cx;
next.xx=tx;next.yy=ty;
}
else if(i==3){
next.cx=now.cx+1;
next.cy=now.cy;
next.xx=tx;next.yy=ty;
}
else{
next.cx=now.cx;next.cy=now.cy;
next.xx=tx;next.yy=ty;
}
q.push(next);
}
}
}
int main()
{
scanf("%d %d",&n,&m);
scanf("%d %d",&r,&c);
scanf("%d %d",&x,&y);
for(int i=0;i<n;i++){
scanf("%s",maps[i]);
}
r--,c--;
bfs(r,c);
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maps[i][j]=='+'){
ans++;
}
}
}
printf("%d\n",ans);
return 0;
}