思路:假装没有这一题
roblem B: Zeratul与翻转黑白棋
思路:皮这一下很开心=W=!
思路:算一下 数量然后就输出……
代码:
#include
using namespace std;
int n;
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
int main()
{
char ch;int temp;
scanf("%d",&n);scanf(" %c",&ch);
int a[100];
a[1]=1;
for(int i=2;i<13;i++){
a[i]=a[i-1]+2*(2*i-1);
}
for(int i=1;i<13;i++)
{
if(a[i]>n) {
temp=i-1;
break;
}
}
for(int i=0;i=0;i--)
{
for(int j=0;j
Time Limit:3000/1000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:87 Accepted:20
[Submit][Status][Discuss]
由于LabMem的工作需要,冈部经常在世界线间穿梭。不同世界线间的差别非常细微,确定当前处在哪一世界线成了困扰冈部的一个难题。好在他发现,世界线的变动只和nn个特定的数有关,这些数的和可以直接用来确定世界线。这组数被称为世界线数。
只有两种情况可以引起世界线数变化。
情况一,每次跳跃世界线时,命运石之门都会给出三个整数l,r,xl,r,x,并将第ll个到第rr个世界线数统一赋值成xx。这三个整数毫无规律且变化无常,所以冈部只能在跳跃过程中将其一一记录。
情况二,一个名为的SERN组织有时会做一些实验,引起世界线的不稳定,这会导致冈部从某个世界线直接掉回到之前到过的一个世界线,并且世界线数变回当时的数值。
现在冈部正在进行一系列的世界线跳跃,他记录下了每次跳跃的l,r,xl,r,x三个参数。每次世界线不稳定时,他都会记录这次掉回的是第几次跳跃后的世界线。他将记录好的数据第一时间告诉你,并希望你能在第一时间帮他算出当前世界线数的和。
本题数据组数:4。
第一行一个整数nn,表示世界线数的个数。
第二行nn个整数aiai,代表世界线数。
第三行一个整数mm,代表即将发生的事件个数。
接下来mm行,每行描述一个事件。有如下三种输入
1 ll rr xx(表示发生情况一事件,世界线数按情况一中描述改变)
2 tt(表示发生情况二事件,冈部掉回第tt个事件执行后,第t+1t+1个事件未执行时的世界线,并且保证只会掉到之前的世界线)
3(表示询问事件,输出当前世界线数的和)
1≤n,m≤10001≤n,m≤1000,1≤l≤r≤n,0≤t≤n,0≤x,ai≤10001≤l≤r≤n,0≤t≤n,0≤x,ai≤1000
对于每个询问3,输出结果
5
1 2 3 4 5
4
1 2 4 6
3
2 0
3
24
15
注意,跳跃,回掉和询问都是事件
Zeratul看了这个题,大喊一声:这不是SB可持久化线段树吗?n和m的数据范围为什么不改成100000?
思路:这不是傻逼可chi'持久化线段树.....暴力吗......记录下状态就行。
#include
using namespace std;
int n;int a[1010][1010];
int ans[1010];
int main()
{
int t,m;int nowans;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i][0]);
}
scanf("%d",&m);int now=0;
for(int mi=1;mi<=m;mi++)
{
int choi;
scanf("%d",&choi);
if(choi==3)
{
int sum=0;
for(int i=1;i<=n;i++)
{
a[i][mi]=a[i][mi-1];
sum+=a[i][mi];
}
printf("%d\n",sum);
}
if(choi==2)
{
int tiao;
scanf("%d",&tiao);
for(int i=1;i<=n;i++)
{
a[i][mi]=a[i][tiao];
}
}
if(choi==1)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
for(int i=1;i<=n;i++)
{
a[i][mi]=a[i][mi-1];
if(i>=x&&i<=y){
a[i][mi]=c;
}
}
}
}
return 0;
}
Time Limit:3000/1000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:75 Accepted:47
[Submit][Status][Discuss]
(我们永远的)大哥有很多的小弟(n个)。每一个小弟有一个智力值。现在小弟们聚集在了大哥身旁,排成了一队,等待大哥的检阅。n个小弟的智力值是一个1到n的排列。大哥在检阅小弟时,每次会选择一些相邻的小弟,让他们按照自己的智力值从小到大或从大到小顺序重新排队(没有被选择的小弟位置不变),以便他排除其中的二五仔。在大哥检阅完小弟之后,老仙突然来了。他十分想为难一下大哥,所以他问大哥其中某一个小弟的智力值是多少。大哥十分的慌,并不能回答这个问题,所以让你来帮他解决这个问题。如果你能够解决,大哥可能会赠与你守护者的三叉戟和并教你他的换家绝学。
本题数据组数:8。
第一行3个整数nn,qq,kk,表示小弟的数目,大哥检阅小弟时让一些小弟重新排队的次数,以及最后老仙问他的是第几个小弟的智力值。
第二行n(1≤n≤20)n(1≤n≤20)个整数,表示每个小弟的智力值,保证符合题意,是11到nn的一个排列。
接下来q(1≤q≤20)q(1≤q≤20)行,每行3个整数aa,bb,t(1≤a≤b≤n,0≤t≤1)t(1≤a≤b≤n,0≤t≤1),表示他选择了第aa个到第bb个小弟(a,ba,b均包含)进行重新排列。若t=0t=0,则为从小到大;若t=1t=1,则为从大到小。
输出一个整数,代表在检阅之后第k个小弟的智力值是多少。
5 2 4
1 4 3 2 5
1 3 0
3 5 1
4
对样例的解释:
第一次操作之后,排列变为:1 3 4 2 5
第二次操作之后,排列变为:1 3 5 4 2
第四个数是4,所以输出4。
[Submit][Status][Web Board]
思路:暴力模拟。。。
#include
using namespace std;
int n;
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
int a[100];
int cmp(int x,int y){
return x>y;
}
int main()
{
int t,q;int x,y,choi;
scanf("%d%d%d",&n,&t,&q);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=t;i++)
{
scanf("%d%d%d",&x,&y,&choi);
if(choi==0){
sort(a+x,a+y+1);
}
else{
sort(a+x,a+y+1,cmp);
}
}
printf("%d",a[q]);
return 0;
}
Time Limit:3000/1000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:103 Accepted:21
[Submit][Status][Discuss]
想象一下,如果在遥远的将来,有一天,虵,离开了我们的世界。届时,无数事物都将随虵而去。比如1,9,2,6四个数码,就将不再存在。那么现在大膜法师Kyurem想让你为残酷的末世做一做心理准备,所以你需要能够回答以下两种问题:
1.在没有虵的世界里,第kk个正整数是多少?
2.在没有虵的世界里,nn是第几个正整数?
如前10个正整数是:3,4,5,7,8,30,33,34,35,37。
大膜导师Kyurem会考验你以上两种问题共计qq次,对于每次你都要立刻给出正确的结果。
本题数据组数:3
输入数据第一行一个整数q(1≤q≤1000)q(1≤q≤1000),表示问问题的次数。
接下来qq行,每行2个整数。第一个数1或2,表示问的问题是1或2。若第一个数是1,第二个数表示k(1≤k≤109)k(1≤k≤109);若第一个数是2,第二个数表示n(1≤n≤109)n(1≤n≤109)。
对于每一行输入,输出对应的答案。
2
1 5
2 5
8
3
输出的答案(如虵的寿命一样)可能超过int的范围,也就是说你可能需要使用其他范围更大类型如long long int,当然不限于此。
[Submit][Status][Web Board]
思路:就是六进制和十进制间的转换......
#include
using namespace std;
int n;int f[6]={0,3,4,5,7,8};
long long num[40];int ni[11]{0,0,0,1,2,3,0,4,5,0};
int main()
{
int t;long long k;int choi;
scanf("%d",&t);
num[0]=1;
for(int i=1;i<=12;i++)
{
num[i]=num[i-1]*6;
// printf("%lld\n",num[i]);
}
while(t--)
{
scanf("%d",&choi);
if(choi==1)
{
scanf("%lld",&k);int flag=0;
for(int i=11;i>=0;i--)
{
if(k/num[i]==0)
{
if(flag==1) printf("0");
}
else{
printf("%d",f[k/num[i]]);
flag=1;
}
k=k-(k/num[i])*num[i];
}
printf("\n");
}
if(choi==2)
{
long long ans=0;int i=0;
scanf("%lld",&k);
while(k>0){
ans+=ni[k%10]*num[i];i++;
k/=10;
}
printf("%lld\n",ans);
}
}
}
Time Limit:7000/5000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:122 Accepted:16
[Submit][Status][Discuss]
昆特牌是风靡巫师大陆的一种卡牌游戏。与大陆上其他商人一样,杰洛特非常喜欢这个游戏,直到他遇到了一个手中全是英雄牌的神棍……杰洛特觉得这个游戏不应该只靠卡牌好坏取胜,于是他设计了一种佛系昆特牌。
佛系昆特牌中只有战士和鼓舞两种卡牌,战士可以对敌方造成一定点数的伤害(不同等级的战士牌造成的伤害不同),而鼓舞则可以提升战士的伤害点数(不同等级的鼓舞牌提升的点数也不同),鼓舞牌可以无限次使用,提升的伤害点数叠加。
游戏开始时,玩家需要选出 nn 张战士牌和 nn 张鼓舞牌,按顺序排好(编号1到 nn)。每一轮游戏,昆特牌系统给出两个随机数l,rl,r。代表这一轮对 ll 到 rr 号战士分别使用第 ll 到 rr 张鼓舞牌一次。最后一轮游戏结束后,将所有战士牌的伤害点数(包括鼓舞牌提升的点数)相加,便得到对敌人的伤害总数值。
杰洛特给你了nn张战士牌和nn张鼓舞牌的排列,他想让你算出在已知昆特牌系统给出的随机数的情况下,他的排列方案中每个战士牌的伤害数值是多少。
本题数据组数:3。
第一行两个正整数nn和mm,代表选出nn张战士牌,游戏共有mm轮。
第二行nn个整数ai(0≤ai≤100)ai(0≤ai≤100),其中aiai代表ii位置战士牌的伤害点数。
第三行nn个整数bi(0≤bi≤100)bi(0≤bi≤100),其中bibi代表第ii张鼓舞牌可以提升的伤害点数。
之后的mm行,每行有两个正整数ll和rr,其中第ii行的数lili和riri代表第i轮昆特牌系统选出的两个随机数。
数据中1≤n,m≤106,1≤li≤ri≤n1≤n,m≤106,1≤li≤ri≤n。
一行nn个整数,代表mm轮游戏后每个战士牌的伤害数值。
5 2
1 2 3 4 5
5 4 3 2 1
1 3
3 5
6 6 9 6 6
你需要设计一个较为高效的算法,否则会TLE。
输入数据共有约40M,请使用较快的I/O方式。
思路:用一个差分数组记录一次加成,然后求前缀和就是该士兵鼓舞次数。(差分数组即d[i]=f[i]-f[i-1])
#include
using namespace std;
int n;
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
int a[1000010];
int b[1000010];
int num[1000200];
int main()
{
int m,q;int x,y,choi;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
while(m--)
{
scanf("%d%d",&x,&y);
num[x]++;num[y+1]--;
}
for(int i=1;i<=n+1;i++)
{
num[i]=num[i]+num[i-1];
}
for(int i=1;i<=n;i++)
{
printf("%d",a[i]+num[i]*b[i]);
if(i!=n) printf(" ");
}
return 0;
}
Time Limit:3000/1000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:80 Accepted:11
[Submit][Status][Discuss]
阅读并理解上图中的程序(s1,s2,s3为三个char类型数组),求出对于正整数xx和kk,调用f(x)f(x)后上图程序输出的第kk个字符是什么。
本题数据组数:11。
前三行每行一个字符串,分别代表s1,s2,s3,字符串只含小写字母,长度不超过20。
第四行两个正整数x,kx,k,意义见描述。
数据保证x≤100,k≤1018x≤100,k≤1018
输出一行一个字符,意义见描述。如果f(x)f(x)输出的总字符数小于kk输出gg。
ab
cd
ef
2 10
d
思路:设len[i]为f(i)输出字符串长度 则 len[i]=len[i-1]*2+strlen(s1)+strlen(s2)+strlen(s3); 那么可以o(1)判断要输出的字符是在5段中的哪一段然后递归即可。
#include
using namespace std;
int n;
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
char s1[30];char s2[30];char s3[30];long long num[200];long long e18=1e18;
int len1,len2,len3;int big;
char findch(int x,long long k)
{
// printf("%d %lld\n",x,k);
if(x>big)
{
if(k<=len1) return s1[k-1];
else
return findch(x-1,k-len1);
}
if(k<=len1)
{
return s1[k-1];
}
if(k<=len1+num[x-1]&&x!=1){
return findch(x-1,k-len1);
}
if(k<=len1+num[x-1]+len2)
{
return s2[k-len1-num[x-1]-1];
}
if(k<=len1+num[x-1]+num[x-1]+len2&&x!=1)
{
return findch(x-1,k-len1-num[x-1]-len2);
}
return s3[k-(len1+num[x-1]+num[x-1]+len2)-1];
}
int main()
{
int m,q;int x,y,choi;long long k;
scanf("%s",s1); scanf("%s",s2); scanf("%s",s3);
scanf("%d",&x);scanf("%lld",&k);
len1=strlen(s1); len2=strlen(s2); len3=strlen(s3);
int len=strlen(s1)+strlen(s2)+strlen(s3);
num[1]=len;
for(int i=2;i<101;i++)
{
num[i]=2*num[i-1]+len;
// printf("%lld\n",num[i]);
if(num[i]>=e18){
big=i;
// printf("%lld %d\n",num[big],big);
break;
}
}
if(num[x]
欧拉回路<======点这里
极大极小值搜索
kmp+dp
树状数组
二分查找+线段树~~