A. DZY Loves Hash
题意:给你n个数字,对他们进行hash,hash的具体操作就是就是把他们放到m个数组里面,比如x放到第x%m+1个数组里面,问是否会有冲突,有输出第几个最先出现冲突,没有输出-1
思路:简单模拟
代码:
#include<bits/stdc++.h>
using namespace std;
int a[310];
int main(){
int n,m;
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
bool judge=false;
for(int i=0;i<m;i++){
int temp;
scanf("%d",&temp);
if(judge)
continue;
if(a[temp%n]){
printf("%d\n",i+1);
judge=true;
}
else{
a[temp%n]=1;
}
}
if(!judge)
printf("-1\n");
}
B. DZY Loves Strings
题意:给你一个字符串,让你在最后补充n个字母,同时a-z每个字母都有自己的价值,问,在原字符串的基础上,补充了n个字母以后,整个字符串最大价值是多少
思路:简单贪心,补充的都是价值最大的即可
代码:
#include<bits/stdc++.h>
using namespace std;
int a[26];
int main(){
char b[1010];
scanf("%s",b);
int n;
scanf("%d",&n);
for(int i=0;i<26;i++)
scanf("%d",&a[i]);
int x=strlen(b);
int val=0;
for(int i=0;i<x;i++){
int temp=b[i]-'a';
val+=(i+1)*a[temp];
}
int maxn=a[0];
for(int i=1;i<26;i++)
maxn=max(maxn,a[i]);
for(int i=0;i<n;i++)
val+=(i+1+x)*maxn;
printf("%d\n",val);
}
C. DZY Loves Sequences
题意:给你一个数列,现在允许你改变最多一个数字,问能够最长多少连续上升的子序列
思路:预处理,我们可以先预处理出来之前包含第i个数字的最长连续上升子序列和之后包含第i个数字的最长连续上升子序列,然后,我们就可以处理这个数列,对于第i个数字,如果第i+1个数字减去第i-1个数字的值大于1,那么我们就可以利用i将i-1和i+1这两部分连起来,如果第i+1个数字减去第i-1个数字的值不大于1,那我们只能改变i使得i-1和i+1的部分分别+1了,然后在这个过程寻找最大值就好了
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn= 1e5+10;
int a[maxn];
int c[maxn];
int d[maxn];
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
c[0]=1;
for(int i=1;i<n;i++)
{
if(a[i]>a[i-1])
c[i]=c[i-1]+1;
else
c[i]=1;
}
d[n-1]=1;
for(int i=n-2;i>=0;i--){
if(a[i]<a[i+1])
d[i]=d[i+1]+1;
else
d[i]=1;
}
int ans=max(d[1]+1,c[n-2]+1);
for(int i=1;i<n;i++){
if(a[i+1]-a[i-1]>1)
{
ans=max(ans,c[i-1]+1+d[i+1]);
}
else{
ans=max(ans,c[i-1]+1);
ans=max(ans,d[i+1]+1);
}
}
printf("%d\n",ans);
}
D - DZY Loves Modification
题意:给你一个矩阵,现在进行k次操作,第一种是选择某一行,让这行都减去q,另一种操作是选某一列,让这一列都减去q,这两种操作,都能获得操作之前的这行(列)所有值的和,问经过k次操作后,最多能获得多少值
思路:思维+预处理+优先队列,首先,我们不管在选择行还是列,肯定是优先选择最大的,而我们选择了x行,就会选择k-x列,然后,我们每次选一行进行操作,这个操作对于每一列的影响都是一样的,而我们选列时也是同理,所以,我们选择行时,是不会影响到列的选择的,可是,不会影响列的选择,但是会影响到列选择后的数值,我们通过画图,能发现,假如我们选择x列,k-x行,那么我们每行产生的影响就是q*(k-x),一共x行,就产生了x*q*(k-x)的影响,然后,我们只需要预处理出选择1-k个行(列)时候的数值,就能通过枚举行数,得到对应列数,同时得到对应影响数值,这样就能得到每种情况下的最后的答案了
代码:
#include<bits/stdc++.h>
using namespace std;
long long a[1010][1010];
long long b1[1010000],b2[1010000];
int n,m,k,p;
priority_queue<long long> q1;
priority_queue<long long> q2;
int main(){
scanf("%d%d%d%d",&n,&m,&k,&p);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%I64d",&a[i][j]);
for(int i=0;i<n;i++){
long long temp=0;
for(int j=0;j<m;j++)
temp+=a[i][j];
q1.push(temp);
}
for(int i=0;i<m;i++)
{
long long temp=0;
for(int j=0;j<n;j++)
temp+=a[j][i];
q2.push(temp);
}
b1[0]=b2[0]=0;
for(int i=1;i<=k;i++){
long long temp=q1.top();
b1[i]=b1[i-1]+temp;
q1.pop();
q1.push(temp-(long long)m*p);
}
for(int i=1;i<=k;i++){
long long temp=q2.top();
b2[i]=b2[i-1]+temp;
q2.pop();
q2.push(temp-(long long)n*p);
}
long long ans=(long long)b2[k];
for(int i=1;i<=k;i++){
ans=max(ans,(long long)b1[i]+(long long)b2[k-i]-(long long)(i)*p*(k-i));
}
printf("%I64d\n",ans);
}