time limit per test
1.0 s
memory limit per test
256 MB
input
standard input
output
standard output
如果莫名流泪,也许是失去了什么美好的回忆。
伪装成人类少女夏弥的龙王耶梦加得曾在暗中默默观察了这个名叫楚子航的男孩很多年。后来,她以学妹的身份正面出现在楚子航身边,一边作战,一边还讲着白烂的吐槽。她将利爪刺进他的胸膛,他也将折刀送入她的心口,他们紧紧相拥,像是最亲密的恋人。他最终来到了她生活过的小屋,仰面躺在床上,阳光温软,但眼泪却没有止住。爱唱歌的女孩被埋在花下了,连带着她的野心、和谜一样的往事。终于有一天有人问起他是不是喜欢她,他用一个问题回避了:"你们都叫她小龙女吗?"
后来,他每天都来看她曾经生活过的小屋,期待着那个虚幻的影子。终于有一天日暮,他又来到了这里,然而却被一串嬉笑声吸引——一个穿着天蓝色校服的女孩在和一个像是痴呆的哥哥在花园旁的空地上画着网格玩。
突然,女孩向它招手:"楚师兄,一起来玩格点正方形的游戏嘛?"
一脸惊喜表情的楚子航却有些疑惑那是什么游戏,她真的是越来越融入人类生活了啊...
"我来画一个 n×mn×m 的网格图,师兄你来数一数上面有多少个正方形呀",她调皮地眨着眼睛。
夕阳的余晖下,三人的影子显得非常的和谐。
Input
第一行输入一个正整数 T (1≤T≤100)T (1≤T≤100),表示数据组数。
接下来 TT 组数据,每组数据输入两个正整数 nn 和 m (1≤n,m≤105)m (1≤n,m≤105),由空格间隔开,表示这个网格图的长为 nn,宽为 mm。
Output
对于每组数据,请输出一个非负整数,表示这个网格图中有多个本质不同的格点正方形,注意换行。
Example
input
Copy
2 1 1 2 2output
Copy
1 6Note
格点正方形:在 n×mn×m 的网格图中,四个顶点都在格点上的正方形叫做格点正方形。
本质不同:若两个格点正方形它们至少有一个顶点不重合在同一个格点上,则将它们称作本质不同的格点正方形
解法:n*m min=min(m,n) ans+=(n-i)*(m-i)*(i+1) i=0~min
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long n,m;
scanf("%lld%lld",&n,&m);
long long sum=0,sum2=0;
int mii=min(n,m);
for(int i=0;i<mii;i++)
{
sum+=(n-i)*(m-i)*(i+1);
}
printf("%lld\n",sum);
}
}
time limit per test
1.0 s
memory limit per test
256 MB
input
standard input
output
standard output
天天最近买了一台思维吃来玩赛尔逵传说。
赛尔逵传说需要玩家扮演近侍骑士森克从恶魔噶里嗷的手里救下赛尔逵公主。但是救出公主的路途异常艰险,噶里嗷在去城堡的路途上设置了 nn 只怪兽来阻挡森克,这 nn 只怪兽分别编号从 11 到 nn。其中第 ii 只怪兽血量为 didi 攻击力为 xixi。
已知森克的攻击力为 kk,他将按顺序轮流与这些怪兽进行若干次回合制战斗。在回合制战斗中,被攻击者会损失攻击者攻击力大小的血量,当被攻击者血量掉到 00 及以下就会立即死亡。每个回合都由森克主动对怪兽发起一次攻击(森克始终先手攻击怪兽),如果怪兽尚未死亡,那么它在本回合就会立即反击森克一次,即森克被攻击后损失该只怪兽攻击力大小的血量,如此循环直到其中某一战斗方死亡为止。
森克为了确保能救出公主,提前准备了 cc 份"力量炖水果",每份"力量炖水果"都可以在瞬间吃下并使森克本回合临时增加 kk 点攻击力,而且一回合内森克可以连续吃许多份"力量炖水果"。请问,森克如果想要救下赛尔逵公主的话,最少需要消耗多少血量呢?
Input
输入共 n+1n+1 行,第一行输入三个正整数 n,k,c (1≤n≤105,1≤k,c≤106)n,k,c (1≤n≤105,1≤k,c≤106) 由空格间隔开,分别表示怪物数 nn,森克的攻击力 kk 与他烹饪的"力量炖水果"数量 cc。
接下来 nn 行,第 ii 行输入两个正整数 didi 和 xi (1≤di,xi≤106)xi (1≤di,xi≤106),分别描述第 ii 只怪兽的血量与攻击力。
Output
请输出一个非负整数,表示森克救下公主最少消耗的血量。
Examples
input
Copy
1 5 3 21 3output
Copy
3input
Copy
2 3 1 3 3 4 5output
Copy
0Note
对于第一组样例,第一回合森克可以连吃三份"力量炖水果",获得三倍的攻击加成,此时他的攻击力达到 2020 点,本回合将怪兽打到只剩 11 点血量,同时本回合他也受到了来自怪兽的 33 点伤害。第二回合,森克的攻击加成消失,而且也没有"力量炖水果"可以吃了,所以他的攻击力回退到 55,但是由于怪兽仅剩 11 点血量,而且森克先手,所以他本回合可以直接将怪兽打死,不用承受本回合怪兽的伤害。因此,打完这只怪兽,森克承受的总伤害为 33 点,即他至少需要消耗 33 点血量才能救下公主。
解法:贪心、按攻击力排序、尽全力攻击伤害最大的
cmp格式:
int cmp(node a,node b) { return a.x>b.x;//此处比较函数需要注意 }
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node
{
int d,x;
};
struct node aa[100005];
int cmp(node a,node b)
{
return a.x>b.x;//此处比较函数需要注意
}
int main()
{
ll n,k,c;
scanf("%lld%lld%lld",&n,&k,&c);
ll sum=0;
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&aa[i].d,&aa[i].x);
}
sort(aa,aa+n,cmp);
for(int i=0;i<n;i++)
{
if(k>=aa[i].d) continue;
if(c)
{
ll kk;
if(aa[i].d%k==0) kk=aa[i].d/k;
else kk=aa[i].d/k+1;
kk--;
if(c>=kk) c-=kk;
else
{
aa[i].d-=( c +1)*k;
sum+=aa[i].x;
long long int cc=(aa[i].d-1)/k;
sum+=cc*aa[i].x;
c=0;
}
}
else
{
ll cc=(aa[i].d-1)/k;
sum+=cc*aa[i].x;
}
}
printf("%lld\n",sum);
}
time limit per test
1.0 s
memory limit per test
256 MB
input
standard input
output
standard output
栈就是像 "只有一端开口的瓶子" 一样的数据结构,大家可以理解为一个头部固定的数组,无论是取出数字还是放入数字,你都只能在数组末尾那一端(称为栈顶)修改。
非常喜欢数据结构的周老师又在给新加入 ACM 俱乐部的小萌新们传授他的人生经验......
这天,周老师得到了一个乱序的全排列,其中 1⋯n1⋯n 共 nn 个数字,每个数字都恰好只出现一次。但是周老师不喜欢无序的东西,所以他总想要把这个数列弄成一个递增的新数列。但是他现在手里恰好只有一些简单的数据结构—— kk 个栈。这些栈一开始全都为空,周老师想要只通过 33 种操作,把初始的序列变成有序的新序列:
- 取出序列当前的第一个数字,插入到第 pp 个栈的顶部:push p
- 取出第 pp 个栈的顶部数字,插入到新序列的末尾位置:pop p
- 取出第 pp 个栈的顶部数字,插入到第 qq 个栈的顶部:move p q
周老师非常的睿智,他一下就想到了如果持有的栈的个数大等于数字总个数(也就是 k≥nk≥n),那么一定可以完成这项排序工作。作为本次数据结构专题讲课的作业题,周老师想考考身为小萌新的你,至少需要多少个这样的栈才能把给定的初始序列变成有序的新序列呢?换句话说,周老师想知道 kk 的最小值 min{k}min{k} 是多少。
Input
第一行输入一个正整数 T (1≤T≤100)T (1≤T≤100),表示数据组数。接下来 TT 组数据,每组数据均满足:
- 第一行输入一个正整数 n (1≤n≤105)n (1≤n≤105),表示本组数据输入的全排列序列长度。
- 第二行输入 nn 个由空格间隔开的正整数 p1,p2,⋯,pnp1,p2,⋯,pn,描述全排列序列 PP 的组成元素。请注意该序列是有顺序的,操作 11 只能从前往后取数字。输入保证 [1,n][1,n] 中每个正整数在 p1⋯ pnp1⋯ pn 中恰好只出现一次。
Output
对于每组数据,请输出一个正整数 kk,表示至少需要 kk 个这样的栈才能把给定的初始序列变成有序的新序列。
Example
input
Copy
3 3 3 2 1 2 1 2 3 2 3 1output
Copy
1 1 2Note
对于第一组数据,一种有效的方法是依次执行如下操作,即可只使用一个简单栈便处理完:
- push 1
- push 1
- push 1
- pop 1
- pop 1
- pop 1
对于第二组数据,一种有效的方法是依次执行如下操作,即可只使用一个简单栈便处理完:
- push 1
- pop 1
- push 1
- pop 1
对于第三组数据,显然一个栈无法处理,至少需要两个栈来处理。
解法:发现最多只需要2个栈,所以非1即2,判断能否只用一个栈进行排序,如不能则需要2个
而且当只用一个栈时,只有两个操作
入栈 和 出栈 (注意!不能直接跳过栈 直接加到新数组后面 没有此操作)
当a[i]的值小于栈顶数时,入栈,如果大于栈顶,栈顶入数组,直到a[i]小于栈顶数
遍历完后,把栈中所有的数加到数组中,判断是否递增,如不递增则输出2,递增则输出1;
/
栈的用法
#include<bits/stdc++.h> using namespace std; int a[100005],b[100005]; int main() { int t; scanf("%d",&t); while(t--) { int n,qq=0; scanf("%d",&n); stack<int> sta; for(int i=0;i<n;i++) { a[i]=0; b[i]=0; } sta.push(0x3f3f3f3f); 无穷大 栈始终不为空 第一个值满足小于栈顶则可以入栈 int fz=0,fj=0; for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(i>=1&&a[i]>a[i-1]) fz++; if(i>=1&&a[i]<a[i-1]) fj++; } if(fz==n-1||fj==n-1) { cout<<1<<endl; continue; } for(int i=0;i<n;i++) { if(a[i]<sta.top()) 如小于 入栈 { sta.push(a[i]); } else 否则栈顶入队列 { while(a[i]>sta.top()) 直到小于栈顶 { b[qq++]=sta.top(); 栈顶数加入数组 sta.pop(); } sta.push(a[i]); 入栈 } } while(sta.size()-1)栈中数入数组 { b[qq++]=sta.top(); sta.pop(); } int ans=1; for(int i=1;i<n;i++) { if(i>=1&&b[i]>b[i-1]) continue; else 如果不递增 则输出2 { ans=2; break; } } cout<<ans<<endl; } }