陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 n个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个 t厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知 n个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度h,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。
输入包括三行数据
第一行为n,h和t分别表示院子中苹果的数量,陶陶伸手能达到的高度和板凳的高度
第二行包含 n 个 100到 200 之间(包括 100 和 200 )的整数分别表示 n 个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。
输出包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
10 110 30
100 200 150 140 129 134 167 198 200 111
5
直接令陶陶的身高为H+T
判断有几个苹果小于H+T即可
#include
using namespace std;
const int N = 1e5+10;
int n,h,t;
int a[N];
int Ans = 0;
int main(){
scanf("%d %d %d",&n,&h,&t);
for (int i = 1; i <= n; i++) scanf("%d",&a[i]);
int H = h+t;
for (int i = 1; i <= n; i++) Ans+=(H>=a[i]);
printf("%d",Ans);
return 0;
}
现在有q个询问
每个询问给出一个n和x,试计算在区间 1 到 n的所有整数中,数字 x(0<=x<=9)共出现了多少次?例如,在 1 到 11中,即在 1,2,3,4,5,6,7,8,9,10,11 中,数字 1 出现了 4 次。
请你给出这q个询问中每个询问的答案
第一行一个整数q,表示一共有q个询问
第2~q+1行,每行2个整数n和x
q行,每行一个整数,对应相应询问的答案
2
11 1
12 2
4
2
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1 0 6 1\le n\le 10^6 1≤n≤106, 0 ≤ x ≤ 9 0\le x \le 9 0≤x≤9。
同样是一题很简单的模拟
直接循环一遍再累加即可
注意回答每个询问一下要重置变量
#include
using namespace std;
int q;
int n,x;
int Ans = 0;
int Plus(int xx,int m){
int anss = 0;
while (xx) anss+=((xx%10)==m),xx/=10;
return anss;
}
int main(){
scanf("%d",&q);
while (q--){
Ans = 0;
scanf("%d %d",&n,&x);
for (int i = 1; i <= n; i++) Ans+=Plus(i,x);
printf("%d\n",Ans);
}
return 0;
}
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个十进制数 56 56 56,将 56 56 56 加 65 65 65(即把 56 56 56 从右向左读),得到 121 121 121 是一个回文数。
又如:对于十进制数 87 87 87:
STEP1: 87 + 78 = 165 87+78=165 87+78=165
STEP2: 165 + 561 = 726 165+561=726 165+561=726
STEP3: 726 + 627 = 1353 726+627=1353 726+627=1353
STEP4: 1353 + 3531 = 4884 1353+3531=4884 1353+3531=4884
在这里的一步是指进行了一次 N N N 进制的加法,上例最少用了 4 4 4 步得到回文数 4884 4884 4884。
写一个程序,给定一个 N N N( 2 ≤ N ≤ 10 2 \le N \le 10 2≤N≤10 或 N = 16 N=16 N=16)进制数 M M M( 100 100 100 位之内),求最少经过几步可以得到回文数。如果在 30 30 30 步以内(包含 30 30 30 步)不可能得到回文数,则输出 impossible
。
两行,分别是 N N N, M M M。
如果能在 30 30 30 步以内得到回文数,输出格式形如 STEP=ans
,其中 ans \text{ans} ans 为最少得到回文数的步数。
否则输出 impossible
。
10
87
STEP=4
同样是模拟
我们注意到题目一直在重复一个过程:
取倒然后跟原数相加
直到当前数是个回文数
由于这个过程不断重复
所以我们可以设置一个函数去重复这个相加的过程
注意一下终止有两个条件:
1、STEP>30
2、当前数变成了回文数
#include
using namespace std;
const int N = 1e5+10;
string s;
int a[N],b[N];
int n,m;
int Ans = 0;
bool Check(){
int l = 1,r = 50000;
while (a[r] == 0) r--;
while (l <= r){
if (a[l] != a[r]) return 0;
l++ , r--;
}
return 1;
}
void Go(){
int r = 50000;
while (a[r] == 0) r--;
for (int i = r; i; i--) b[r-i+1] = a[i];
for (int i = 1; i <= r; i++) a[i] = a[i]+b[i];
for (int i = 1; i <= r; i++) a[i+1]+=a[i]/m,a[i]%=m;
}
int main(){
scanf("%d",&m);
cin>>s; n = s.length();
for (int i = 0; i < n; i++) a[i+1] = s[i]-48;
while (!Check() && Ans<=30) Go(),Ans++;
if (Ans>30) printf("impossible");
else printf("STEP=%d",Ans);
}
键盘输入一个高精度的正整数 N N N(不超过 250 250 250 位),去掉其中任意 k k k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 N N N 和 k k k,寻找一种方案使得剩下的数字组成的新数最小。
输入两行正整数。
第一行输入一个高精度的正整数 n n n。
第二行输入一个正整数 k k k,表示需要删除的数字个数。
输出一个整数,最后剩下的最小数。
175438
4
13
题目需要我们删除 k k k个数字之后使得最后的数字尽可能小
这个时候我们就要思考,什么时候一个数是尽可能小的?
但是,这道题要求我们删除k个数,所以最后的长度应该是一样的
在此条件下,我们继续思考,在长度一样的情况下,怎么样才能让一个数尽可能小呢?
也就是说,我们通过删数,要使得这个数的高位变得尽可能小
删除什么样的数,能让这个数的高位变小呢?
例如有这个数1324
假设我们只能删一次数,我们会删那个数,让这个数的高位尽可能小呢?
首先,由于我们在意的是高位,所以我们会尽可能的从前往后删
于是我们开始尝试:
删除1可行吗?
显然不行,删除1之后,首位变成了3,整个数的高位变大了
那删除3呢?
好像是可行的,删除3之后,高位1没变,但是后面的一位由3变成了2,确实变小了
删除2呢?
不行,删除2之后,原本2的位置就会由4来顶替,是变大了
删除4?
可行,但是没有删除3的受益来的大
经过刚才的尝试,我们似乎找到了一点规律:
假设我们删除第 i i i个位置的数,那么第 i i i个位置的数就会由第 i + 1 i+1 i+1个位置的数去顶替。
那么什么时候删除第 i i i个位置的数,整个数会尽可能变小呢?
那就是第 i i i个位置的数比第 i + 1 i+1 i+1个位置的数要大的时候
这样删除了第 i i i个位置的数的时候就会让更小的第 i + 1 i+1 i+1个位置的数去顶替
这样总的数就变小了
但是光这还不够
我们之前说我们想让高位尽可能小
所以我们会尽可能的先删除高位
我们从前往后寻找,找到第一个符合条件的数就删除
而后重新从前往后再寻找……
直到删除满 k k k个数或者找不到满足条件的数的数为止
从上述条件中可以看出,当我们找不到符合条件的数的时候,我们的删数过程就会停止
那是否有一种情况,我们已经找不到符合条件的数了,但是我们删除的数还没到达 k k k个呢?
当然是有可能的。
那么这个数满足什么条件,他会找不到符合条件的数呢?
显然是单调递增的时候
每一位依次递增,自然不会存在第i位的数比第i+1位的数要大
这个时候,我们只需要从后往前依次删除,直到删满k个数为止
这样总结束了吧……
呵呵,还没有
一些特殊情况你考虑了吗?
比如删完的时候,当前数是0打头的
比如数字50074897删除两次
最后会得到004897这样的数
但是这显然不是一个正常的数啊!
我们需要去掉前导0
于是我们加上了去前导0的操作,松了口气。
你以为这样就好了吗?
呵呵
如果删完数字是000呢?
去完前导0之后这个数不就变成了一个空屁了吗?
这种情况还要特殊判断,需要输出0
这个时候你恐惧了,颤抖的说:“***,肯定还有情况!”
嘿嘿嘿
当然~~~
没了!
至此,这道题终于结束
功德圆满啦!
#include
using namespace std;
string s;
int k;
void Work(int x){
int le = s.length();
string ss = "";
for (int i = 0; i < x; i++) ss+=s[i];
for (int i = x+1; i < le; i++) ss+=s[i];
s = ss;
}
int main(){
cin>>s;
cin>>k;
while (1){
int n = s.length();
bool f = 1;
for (int i = 0; i < n-1; i++)
if (s[i]>s[i+1]){f = 0 , Work(i) , k--; break;}
if (k == 0 || f) break;
}
int Le = s.length();
int st = 0;
while (s[st] == '0' && st<Le-1) st++;
for (int i = st; i <= Le-1-k; i++) cout<<s[i];
return 0;
}
小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m m m 元。先不要太高兴,因为这些钱还不一定都是你的。接下来主持人宣布了比赛规则:
首先,比赛时间分为 n n n 个时段,它又给出了很多小游戏,每个小游戏都必须在规定期限 t i t_i ti 前完成。如果一个游戏没能在规定期限前完成,则要从奖励费 m m m 元中扣去一部分钱 w i w_i wi, w i w_i wi 为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!
第一行为 m m m,表示一开始奖励给每位参赛者的钱;
第二行为 n n n,表示有 n n n 个小游戏;
第三行有 n n n 个数,分别表示游戏 1 1 1 到 n n n 的规定完成期限;
第四行有 n n n 个数,分别表示游戏 1 1 1 到 n n n 不能在规定期限前完成的扣款数。
输出仅一行,表示小伟能赢取最多的钱。
10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
9950
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 500 1 \le n \le 500 1≤n≤500, 1 ≤ m ≤ 5 × 1 0 5 1 \le m \le 5 \times 10^5 1≤m≤5×105, 1 ≤ t i ≤ n 1 \le t_i \le n 1≤ti≤n, 1 ≤ w i ≤ 1000 1 \le w_i \le 1000 1≤wi≤1000。
真服啦
题目要我们求什么呢?
希望求出我们能取得的最多的钱
最多的钱是什么意思?
扣得钱最少嘛
怎么样扣得钱可以最少呢?
那就是尽量先把扣钱多的项目先做掉嘛
好
这就是这道题贪心的第一个思路:
优先把扣钱多的项目做掉
所以我们需要先把项目按照扣钱数从大到小进行排序
在前面的项目尽可能先做
那么对于一个项目,我们要怎么去做才能做到最优呢?
是在靠后的时间点去做,还是在靠前的时间点去做呢?
对,就是在靠后的时间点去做。
为什么呢?
我们在如果在靠后的时间点把这个项目做掉了,那么我们在前面的时间点就有可能去完成其他的项目
不然,如果我们在前面就把这个项目做掉,就可能导致其他截止时间小的项目无法完成
对吧?
好
这就是我们的第二个贪心思路:
对于一个游戏,我们要在尽可能靠后的时间点去完成,这样才会给其他项目留下更多的额可能
#include
using namespace std;
int m,n;
struct Node{
int t,w;
}a[101001];
bool f[101000];
bool cmp(Node a,Node b){
return a.w>b.w;
}
int main(){
scanf("%d\n%d",&m,&n);
for (int i = 1; i <= n; i++) scanf("%d",&a[i].t);
for (int i = 1; i <= n; i++) scanf("%d",&a[i].w);
sort(a+1,a+n+1,cmp);
for (int i = 1; i <= n; i++){
bool F = 0;
int T = a[i].t;
while (f[T] && T) T--;
if (T == 0) m-=a[i].w;
else f[T] = 1;
}
printf("%d",m);
}