题目编号 标题
0 怪兽
1 白板
2 序列
3 游戏
PYWBKTDA最近正在打怪兽,一个斯拉夫神话中的凶猛怪兽,一个有着多个头的巨大龙状爬行
动物。
开始的时候,怪兽有X个头,你有n种打击方式。如果你选择第i种打击方式,这个神奇的怪兽会减
少min(d i ,cur)个头。这里cur表示当前怪兽拥有的头的数量。但是如果怪兽被打击以后还至少留下
了一个头,那么它就会再长出h i 个头来。当cur = 0或者小于0的时候,怪兽被打败了。
注意,你可以使用任何一种打击方式任何次数,以任何的顺序。
例如,如果当前cur = 10,d = 7,h = 10,那么一次打击以后怪兽就会有13个头了(因为减少了7个
头以后,怪兽还剩下3个头,再加上10个头)。但是如果当前cur = 10,d = 11,h = 100,那么怪兽就被打
败了。
第一行输入是两个整数n和x,分别表示打击的种类和开始时候怪兽的头的数量。
接下来n行, 每行两个整数描述了d i 和h i ,表示第i种打击减少的头的数量和会长出来的头的数量。
输出只有一个整数,表示最少需要打击的次数,如果怪兽无法被打败,就输出−1。
【输入样例1】
3 10
6 3
8 2
1 4
【输入样例2】
4 10
4 1
3 2
2 6
1 100
【输入样例3】
2 15
10 11
14 100
【输出样例1】
2
【输出样例2】
3
【输出样例3】
-1
对于50%的数据,1 ≤ n ≤ 10,1 ≤ x ≤ 100,1 ≤ d i ≤ 100,1 ≤ h i ≤ 100。
对于100%的数据,1 ≤ n ≤ 100,1 ≤ x ≤ 10 9 ,1 ≤ d i ≤ 10 9 ,1 ≤ h i ≤ 10 9 。
样例1,你可以使用第一种打击方式,第一次打击以后剩下(10-6+3=7)个头,再进行第2次打击。
样例2,你可以使用第一种打击方式,攻击3次。
样例3,这里你无法打败怪兽。
这道题爆力,
#include
#include
using namespace std;
long long m,n,k=2147483647,x,y,d[100100],h[100100];
int main(){
freopen("monster.in","r",stdin);
freopen("monster.out","w",stdout);
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>d[i]>>h[i];
}
for(int i=1;i<=n;i++){
if(d[i]>=x){
cout<<1;
return 0;
}
y=d[i]-h[i];
if(y>0){
long long ans=(x-h[i])/y;
if((x-h[i])%y!=0)ans++;
if(ans<k&&ans>0)k=ans;
}
if(y<=0){
if(d[i]>=x){
cout<<1;
return 0;
}
}
}
if(k==2147483647)cout<<-1;
else{
cout<<k;
}
return 0;
}
PYWBKTDA有一块白板,这块白板的四条边分别平行于坐标轴。我们可以假设这块白板的左
下角在(x 1 ,y 1 )位置,右上角在(x 2 ,y 2 )位置。
现在有两块黑板放到白板的上面,这两块黑板的四条边也是平行于坐标轴的。我们可以设第1块
黑板的左下角是(x 3 ,y 3 ),右上角在(x 4 ,y 4 )位置, 第2块黑板的左下角是(x 5 ,y 5 ),右上角在(x 6 ,y 6 )位置。
现在你的任务是来判断,我们从上往下看,是否有白板的部分区域可以被看到。所谓的白板部分
区域被看到的意思是,白板上至少有一个点没有被黑板遮住。
输入第一行有一个整数t,表示数据的组数。
接下来每组数据:
输入的第一行包含4个整数,分别表示x 1 ,y 1 ,x 2 ,y 2 ,即白板的左下角和右上角。
输入的第二行包含4个整数,分别表示x 3 ,y 3 ,x 4 ,y 4 ,即第1块黑板的左下角和右上角。
输入的第三行包含4个整数,分别表示x 5 ,y 5 ,x 6 ,y 6 ,即第2块黑板的左下角和右上角。
输出有t行,对于每组数据,如果有部分白板可以被看到,就输出Y ES,否则就输出NO。
3
2 2 4 4
1 1 3 5
3 1 5 5
3 3 7 5
0 0 4 6
0 0 7 4
5 2 10 5
3 1 7 6
8 1 11 7
NO
YES
YES
第一个例子中,白板被黑板完全覆盖。
第二个例子中,部分白板可以看到。比如(6.5,4.5)这个点就可以被看到。
对于50%的数据:
0 ≤ x 1 < x 2 ≤ 100,0 ≤ y 1 < y 2 ≤ 100。
0 ≤ x 3 < x 4 ≤ 100,0 ≤ y 3 < y 4 ≤ 100。
0 ≤ x 5 < x 6 ≤ 100,0 ≤ y 5 < y 6 ≤ 100。
对于100%的数据:
1 ≤ t ≤ 100。
0 ≤ x 1 < x 2 ≤ 10 6 ,0 ≤ y 1 < y 2 ≤ 10 6 。
0 ≤ x 3 < x 4 ≤ 10 6 ,0 ≤ y 3 < y 4 ≤ 10 6 。
0 ≤ x 5 < x 6 ≤ 10 6 ,0 ≤ y 5 < y 6 ≤ 10 6 。
这道题50分爆力,100分可以用离散化
这里,讲一讲离散化
在很多时候,一些不多但很大的数据,会引发OI最致命的错误
但,离散化可以决绝这个问题
先把这些数排序,再用它们排好序在数列中的位置来做离散化后的值(因为这和它们的大小无关),就完了
代码
#include
#include
#include
#include
using namespace std;
int a[500][500],k;
int zb[13],zb2[13];
int main(){
freopen("sheet.in","r",stdin);
freopen("sheet.out","w",stdout);
int t;
cin>>t;
while(t--){
k=0;
for(int i=1;i<=12;i++){
cin>>zb[i];
zb2[i]=zb[i];
}
sort(zb2+1,zb2+13);
for(int i=1;i<=12;i++){
for(int j=1;j<=12;j++){
if(zb[i]==zb2[j]){
zb[i]=j*2;
break;
}
}
}
for(int xi=zb[5];xi<=zb[7];xi++){
for(int yi=zb[6];yi<=zb[8];yi++){
a[xi][yi]=1;
}
}
for(int xi=zb[9];xi<=zb[11];xi++){
for(int yi=zb[10];yi<=zb[12];yi++){
a[xi][yi]=1;
}
}
for(int i=zb[1];i<=zb[3];i++){
for(int j=zb[2];j<=zb[4];j++){
if(a[i][j]==0){
cout<<"YES"<<endl;
k=1;
break;
}
}
if(k==1)break;
}
memset(a,0,sizeof(a));
if(k==0)cout<<"NO"<<endl;
}
return 0;
}
PYWBKTDA最近在研究一些有趣的数列。
他给你一个无穷序列”112123123412345…”。这个序列是这么构造的,我们先写出1到1的所有整
数,然后写出1到2的所有整数,然后写出1到3的所有整数,这样不断重复进行到无穷。
例如现在前56个数字组成的序列是:
”11212312341234512345612345671234567812345678912345678910”。
我们把序列里面的每个数字从1开始编号,比如编号为1的数字就是1,编号为2的数字也是1,编号
为3的数字是2,编号为20的数字是5,编号为38的数字是2,编号56的数字是0.
现在你的任务是对于题目给出的q个询问,每个询问是k i ,表示问你编号为k i 的数字是多少。
输入格式
第一行是整数q,表示询问的数量。
接下来i行,每行一个整数,表示k i 。
输出共计有q行,第i行的输出表示对应的k i 的询问,显然,每个答案都在0到9之间。
【输入样例1】
5
1
3
20
38
56
【输入样例2】
4
2132
506
999999999
1000000000
【输出样例1】
1
2
5
2
0
【输出样例2】
8
2
9
8
对于30%的数据, 1 ≤ k i ≤ 10 5 。
对于70%的数据,1 ≤ k i ≤ 10 9 。
对于100%的数据,1 ≤ k i ≤ 10 18 ,1 ≤ q ≤ 500。
和刘震巨佬说的一样,70分不难,但麻烦
#include
#include
#include
using namespace std;
long long m,n,k,x,y,y1;
long long a[10000010];
string s;
int main(){
freopen("squence.in","r",stdin);
freopen("squence.out","w",stdout);
int t;
cin>>t;
while(t--){
cin>>k;
y=0;
a[1]=1;
y1=0;
while(y1+a[y+1]<k){
y++;
int xx=y+1;
x=y+1;
y1+=a[y];
if(a[x]!=0)continue;
if(x/1000000000!=0){ a[xx]=a[xx]+(x-999999999)*10;x=999999999; }
if(x/100000000!=0){ a[xx]=a[xx]+(x-99999999)*9;x=99999999; }
if(x/10000000!=0){ a[xx]=a[xx]+x*8-9999999*8;x=9999999; }
if(x/1000000!=0){ a[xx]=a[xx]+x*7-999999*7;x=999999; }
if(x/100000!=0){ a[xx]=a[xx]+x*6-99999*6;x=99999; }
if(x/10000!=0){ a[xx]=a[xx]+x*5-9999*5;x=9999; }
if(x/1000!=0){ a[xx]=a[xx]+x*4-999*4;x=999; }
if(x/100!=0){ a[xx]=a[xx]+x*3-99*3;x=99; }
if(x/10!=0){ a[xx]=a[xx]+x*2-9*2;x=9; }
if(x/1!=0){ a[xx]=a[xx]+x; }
}
x=k-y1;
long long i=0,j,k;
while(x>0){
i++;
j=i,k=0;
while(j!=0){
k++;
j=j/10;
}
x-=k;
}
x+=k;
while(i!=0){
char c=(i%10)+48;
s=c+s;
i=i/10;
}
cout<<s[x-1]<<endl;
s="";
}
return 0;
}
PYWBKTDA很喜欢玩一些游戏,比如算21点。他最近迷上了一款弹珠游戏。
有n个弹珠排成一排,第i个弹珠的颜色是a i 。 PYWBKTDA喜欢把这些弹珠重新排列,使得相
同颜色弹珠都在同一个连续区间。也就是说,如果PYWBKTDA想要把颜色i的全部放在一起,那
么颜色i弹珠的最左边的位置是l,最右边的位置是r,那么所有颜色为i的弹珠的位置只能在l到r之间,
l到r范围内也只能有颜色i的弹珠。
为了达到这个目的,PYWBKTDA将进行如下操作:找到两个相邻的弹珠,把它们交换一下位
置。
现在你的任务是来计算最小的交换次数,使得相同颜色弹珠都在同一区间,在这个区间内,同
种颜色的弹珠的位置是无关紧要的。
输入的第一行是一个整数n,表示弹珠的数量。
输入的第二行有n个整数a i ,表示第i个位置上弹珠的颜色。
输出只有一个整数,表示最少的交换次数。
【输入样例1】
7
3 4 2 3 4 2 2
【输入样例2】
5
20 1 14 10 2
【输入样例3】
13
5 5 4 4 3 5 7 6 5 4 4 6 5
【输出样例1】
3
【输出样例2】
0
【输出样例3】
21
对于20%的数据,1 ≤ n ≤ 100,1 ≤ a i ≤ 2。
对于60%的数据,1 ≤ n ≤ 100000,1 ≤ a i ≤ 10。
对于100%的数据,1 ≤ n ≤ 100000,1 ≤ a i ≤ 20。
样例1,在颜色序列[3,4,2,3,4,2,2]中,我们可以把第3个和第4个交换一下,然后把第2个和第3个交换
一下,最后把第4个和第4个交换一下。