(Rating总算回1500了……)
第一题
一道水题……
题意
描述:定义一个6位数是lucky的,当且仅当它的前3位之和等于后3位之和,比如165912。给出数x,找出最小的、大于x的幸运数字。无解输出-1。
输入:一个数,表示x
输出:一个数,表示下一个幸运数字
范围:
样例输入:555555
样例输出:555564
正解
随便枚举一下就行了……
代码
#include<bits/stdc++.h>
using namespace std;
int x;
bool check(int k)
{
int l=0,r=0;
for(int i=1;i<=3;i++)
{
r+=k%10;
k/=10;
}
for(int i=1;i<=3;i++)
{
l+=k%10;
k/=10;
}
if(l==r)return 1;
return 0;
}
int main()
{
scanf("%d",&x);
for(int i=x+1;i<=999999;i++)
if(check(i)){printf("%d",i);return 0;}
printf("-1");
return 0;
}
第二题
T的特别惨,只拿到30……
题意
描述:有两个数组A,B,大小均为N。请在A中选择一个数x,B中选择一个数y,使得gcd(x,y)最大;如果有多组数gcd相同,找出x+y最大的。
输入:第一行一个数n,第二行n个数表示Ai,第三行n个数表示Bi。
输出:输出gcd最大的那对数(gcd相同则和最大)的x+y的值。
范围:
样例输入:5 3 1 4 2 8 5 2 12 8 3
样例输出:16
我原来的思路是枚举,将两数组分别排序,再从大到小进行比较。我还加了一个剪枝,若这个数<maxgcd就可以break了,但是然并卵啊……n上限5e5直接爆炸……
正解
用bool数组存A、B,表示有这个数字(当然数组大小为Ai上限),顺便记录最大值(gcd不会超过这个最大值),再一个双重循环,外层枚举gcd(从大到小),内层枚举另一个因数,若在两数组内都有合法的数,则输出。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;//这里得用Ai和Bi的上限了
int n,maxx=0,x;
bool a[N+10],b[N+10];
inline int read()
{
int N=0,C=1;
char tf=getchar();
while(tf<'0'||tf>'9'){if(tf=='-')C=-1;tf=getchar();}
while(tf>='0'&&tf<='9')N=(N<<1)+(N<<3)+(tf^48),tf=getchar();
return N*C;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)x=read(),a[x]=1,maxx=max(maxx,x);
for(int i=1;i<=n;i++)x=read(),b[x]=1,maxx=max(maxx,x);
for(int i=maxx;i>=1;i--)//gcd<=maxx;
{
int xx=0,yy=0;
for(int j=1;j*i<=maxx;j++)
{
if(a[i*j])xx=i*j;
if(b[i*j])yy=i*j;//gcd(xx,yy)=i;
}
if(xx&&yy){printf("%d",xx+yy);return 0;}
}
printf("1");
return 0;
}
第三题
刷题量严重不足,没有看出来题目知识点……
题意
描述:商场有n件宝贝,每件宝贝有两个属性:价钱price和品牌brand。其中brand是1-5之间某个整数。每件宝贝价钱两两不同。有Q个代言人,每个代言人拍完戏之后,希望能从蓝月商场免费顺走一样宝贝。但是每个代言人有自己的喜好。具体来说,代言人会有d个喜欢的品牌(1 <= d <= 5),同时他最喜欢这些品牌中,价钱第k便宜的宝贝。请你求出每个代言人最喜欢的宝贝的价钱是多少!如果不存在这件宝贝,请输出-1。
输入:第一行一个整数n,第二行n个整数描述每件宝贝的品牌,第三行n个数描述每件宝贝的价钱。第四行一个整数Q,接下来Q*3行,每3行描述一个代言人的信息。其中第一行一个整数d,第二行d个数表示喜欢的品牌,第三行一个数表示k。
输出:一共Q行,每行一个数。
范围:
样例输入:3 1 1 2 1 3 2 3 1 1 2 2 1 2 2 1 3 1
样例输出:3 2 -1
(第一反应当然是暴力啦)
开五个数组分别存五种品牌的宝贝,用的时候挑出来汇总到一个大数组……
(然后就T了一半……)
正解
这题其实是一道状压题(并没有看出来……)f[i][j]表示i状态下第j便宜的宝贝价格,预处理过后查询十分快捷。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+2,M=1<<5;
int n,q,m,k,like,brand;
int f[M][N];//状压+dp,f[i][j]表示i状态下第j便宜的宝贝价格
struct item{int c/*价格*/,d/*品牌*/;}a[N];
inline int read()
{
int N=0,C=1;
char tf=getchar();
while(tf<'0'||tf>'9'){if(tf=='-')C=-1;tf=getchar();}
while(tf>='0'&&tf<='9')N=(N<<1)+(N<<3)+(tf^48),tf=getchar();
return N*C;
}
bool cmp(item x,item y){return x.c<y.c;}//按价格从小到大排
int main()
{
n=read();
for(int i=1;i<=n;i++)a[i].d=read(),a[i].d=1<<(a[i].d-1);//状压
for(int i=1;i<=n;i++)a[i].c=read();
sort(a+1,a+n+1,cmp);
//预处理
for(int i=1;i<M;i++)
for(int j=1;j<=n;j++)
if(a[j].d&i)//枚举子集
f[i][++f[i][0]]=a[j].c;//从小到大记录价格
//主程序
q=read();
for(int i=1;i<=q;i++)
{
m=read();
like=0;
for(int j=1;j<=m;j++)
{
brand=read();
like|=1<<(brand-1);//此位变1
}
k=read();
if(k>f[like][0]/*like状态下不足k个宝贝*/)puts("-1");
else printf("%d\n",f[like][k]);
}
return 0;
}
第四题
(骗分万岁)
这题估计是dp,但是我还是没有搞很懂……
题意
描述:有两个仅包含小写字母的字符串x,y,长度分别为n,m。你需要修改x串中某些字符,是的新的x串和y串的最长公共子序列长度至少为k。
我们将’a’…’z’对应成0…25,修改两个字符付出的代价,为它们对应的数的xor值。比如说,将’a’修改成’z’代价为0 xor25=25。
请问最少付出多少代价,使得新的x串和y串的LCS大于等于k。
输入:第一行三个数n,m,k,第二行长度为n的字符串x,第三行长度为m的字符串y。
输出:最小花费,如果不能请输出-1。(没错输出-1骗到10分……RP--)
范围:
样例输入:7 4 2 merging pair
样例输出:3
正解
动态规划
f[i][j][p]表示A串的前i个和B串的前j个,LCS的长度至少为p时,最少花多少代价。
最后的答案就是f[n][m][k]。
要么不修改,要么改成和B串一样。
代码
(不存在的)
不是很懂,也只能看大佬的了……
第五题
第一眼看出是线段树问题,第二眼看出在我的能力范围之外……
知识没有巩固,现在只会敲模板题,像这题出现阶层这种奇怪的东西就凉凉了……
暴力骗了14……
正解十分玄学……
题意
描述:给出长度为n的序列A1,A2,…,An。进行m次操作,有三种类型:
1、给出l,r,将区间[l,r]的Ai都加一。
2、给出l,r,询问区间[l,r]的Ai!的和,对10^9取模。
3、给出I,v,将Ai单点修改为v。
输入:第一行两个数n,m,第二行n个数Ai。接下来m行,每行三个数,第一个数k,表示第几类操作,后面两个数如题所述
输出:对于每个操作2输出解
范围:
样例输入:5 7 1 1 1 1 1 2 1 5 1 1 5 2 1 5 1 1 3 2 1 5 3 1 15 2 1 5
样例输出:5 10 22 674368016
![](https://i-blog.csdnimg.cn/blog_migrate/63f03b26bd72795ac1e446203c384989.png)
正解
容易(疯狂打表)发现,如果一个数大于等于40,它的阶层%10^9就是0了……(怪我考试没有打表……)
然后在区间修改的时候,只需要把区间内小于40的数拿出来,进行单点+1,不然就根本不用改……
乍一看效率爆炸,然而一个数最多只能被修改50次,所以最多只有(n+q)*50次有效修改
只需用线段树维护区间内最小值的下标,每次单点修改
(一口老血)
代码
(不存在的)
第六题
还是线段树……还是不清楚……看到求和一脸懵逼……
于是果断暴力骗分……
本来这题小分很足(40),但是(手贱)没有用long long,就爆int了……
题意
描述:
输入:
输出:
范围:
输入样例:6 6 8 9 1 13 9 3 1 4 5 2 6 9 1 3 7 2 7 7 1 6 1 2 11 13
样例输出:45 19 21
正解
代码
(不存在的)
总结
后面三题还是没有弄很懂(基本来自老刘的题解)……代码等以后弄懂了再补吧……(还要补集训日记,上次保存的不知道怎么的就丢了……心态爆炸……假如生活欺骗了你)
上次考试考的十分没有耐心,敲完会的就不想思考难题了,最后只A了前两题,后面全爆0……
这次难题也试着思考了,敲了敲也拿(骗)到了一些小分,终于没有上次考倒数的尴尬了……
所以思考很重要,就算题目难,好好想想还是可以拿(骗)到一部分分的……