Q1
简单题
k<=50,可以直接穷举
主代码:
if(n%10==0){
n/=10;
}
else n--;
Q2
首先 每个数字最终要%m
所以:答案<m
做法:
1.a序列全部%m(无需解释)
2.a,b,sort排序
关键点: 将a数组同加一个数并%M,使其等于B数组
如:a=1,1,2,2,2,3,3
b=2,2,3,3,3,4,4
how?
1.找到b中最小数的个数(如:2,2个)
2.在a中找对应个数(如:1,4,都是2个)
3.一一测试正确性并打擂最小值
上代码:
#include<bits/stdc++.h>
using namespace std;
int a[2005],b[2005];
int n,m;
bool check(int l){
int tmp[2005];
for(int i=1;i<=n;i++){
tmp[i]=a[i]+l;
tmp[i]%=m;
}
sort(tmp+1,tmp+n+1);
for(int i=1;i<=n;i++){
if(tmp[i]!=b[i]){
return 0;
}
}
return 1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]%=m;
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
sort(b+1,b+n+1);
sort(a+1,a+n+1);
int sum=1;
while(b[sum+1]==b[sum]) sum++;
int q=n,ans=1000000005;
if(check(0)){
printf("%d",0);
return 0;
}
a[0]=-10000;
for(int i=n-1;i>=0;i--){
if(a[i]!=a[i+1]){
if(q-i==sum){
if(check((m+b[1]-a[i+1])%m)){
ans=min(ans,(m+b[1]-a[i+1])%m);
}
}
q=i;
}
}
printf("%d",ans);
return 0;
}
Q3 若两个学校与A联通且不经过点B,则这两个学校无需同时经过点B
同理:若两个学校与B联通且不经过点A,则这两个学校无需同时经过点A
此时,剩下的学校组合即为必须同时经过A,B
废话不多说:
#include<bits/stdc++.h>
using namespace std;
long long int d[2],sum;
vector<int> aa[100005],aa2[100005];
bool f[100005];
void sss(int l){
sum++;
f[l]=1;
for(int i=0;i<aa[l].size();i++){
if(!f[aa[l][i]]) sss(aa[l][i]);
}
}
void sss2(int l){
sum++;
f[l]=1;
for(int i=0;i<aa2[l].size();i++){
if(!f[aa2[l][i]]) sss(aa2[l][i]);
}
}
int main(){
int n,m,a,b,x,y;
scanf("%d%d%d%d",&n,&m,&a,&b);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
if(x!=a&&y!=a){
aa[x].push_back(y);
aa[y].push_back(x);
}
if(x!=b&&y!=b){
aa2[x].push_back(y);
aa2[y].push_back(x);
}
}
f[a]=1;
sum=0;
sss(b);
d[0]=n-sum-1;
memset(f,0,sizeof(f));
f[b]=1;
sum=0;
sss2(a);
d[1]=n-sum-1;
printf("%lld",d[0]*d[1]);
return 0;
}