今天还是很有必要总结一下牛客网上的 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛。
今天发挥失常,仅出了5题,rank100+。
比赛:埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛
形式:团队赛
队伍出题:5/12
个人出题:2
A:搬沙子使两堆沙子每部分数量一样,求最小步数。很简单的想到如果第一堆沙子多于第二堆就把第一堆多出来的往后搬一格,第二堆多就把第二堆多的往后搬一格。相等就不搬,累加搬得总数量就是答案。然而不要忘了用long long,否则就只能过52%(不要问我怎么知道的,我不知道)
B:这样的题目用到一些思维,比赛时候没做出来有点可惜,不过也算是一种提高,有必要详细说一下。
链接:https://www.nowcoder.com/acm/contest/91/B
来源:牛客网
合约数
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述

输入描述:
输入测试组数T,每组数据,输入n+1行整数,第一行为n和p,1<=n<=20000, 1<=p<=n, 接下来n-1行,每行两个整数u和v,表示u和v之间有一条边。第n+1行输入n个整数val1, val2,…, valn,其中1<=vali<=10000,1<=i<=n.
输出描述:
对于每组数据,输出一行,包含1个整数, 表示对1000000007取模后的结果
我的题解怎么没了???
写了几十行 一发表就没了什么鬼???写了两遍还是没了。。。坑死我了。。。今天优快云有毒
AC代码:
#include<bits/stdc++.h>
#define lson l,mid,t<<1
#define rson mid+1,r,t<<1|1
#define ll long long
using namespace std;
const int maxn=20010;
const int N=20010;
const int mo=1e9+7;
int m,k,x,y,p;
int n,num;
int ans,tmp;
bool us[maxn];
int flag;
int a[maxn],f[maxn],bing[maxn];
int z[maxn],b[maxn],he[maxn];
bool jd[maxn];
vector<int>vc[maxn];
void add(int u,int v)
{
vc[u].push_back(v);
}
void init()
{
int mx=10001;
memset(b,0,sizeof(b));
int i=2,j=2;
for(i=2;i<mx;i++)
{
for(j=2;j*i<mx;j++)
{
b[i*j]=1;
}
}
}
void quyu(int &x){x%=p;if(x<0)x+=p;}
void dfs(int x,int fa)
{
quyu(f[a[x]]+=x);
if(b[a[x]])
for(int i=a[x];i<maxn;i+=a[x])
quyu(ans+=f[i]);
us[x]=1;
for(int i=0;i<vc[x].size();i++)
{
int v=vc[x][i];
if(!us[v]&&v!=fa) {
dfs(v,x);
}
}
us[x]=0;
quyu(f[a[x]]-=x);
}
int main()
{
int T;
init();
scanf("%d",&T);
while(T--){
memset(bing,0,sizeof(bing));
memset(he,-1,sizeof(he));
memset(us,0,sizeof(us));
memset(f,0,sizeof(f));
scanf("%d %d",&n,&m);
num=0;
p=mo;
for(int i=1;i<maxn;i++)
vc[i].clear();
for(int i=0;i<n-1;i++)
{
int u,v;
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
ans=0;
dfs(m,-1);
printf("%d\n",ans);
}
//(flag) puts("Yes");else puts("No");
return 0;
}
/*
2
5 4
5 3
2 5
4 2
1 3
10 4 3 10 5
3 3
1 3
2 1
1 10 1
*/
I:
来源:牛客网
二数
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
换句话说,给定一个十进制下最多10 5位的数字,请你求出和这个数字的差的绝对值最小的二数,若答案不唯一,输出最小的那个。
输入描述:
1 ≤ T ≤ 100, 1 ≤ n ≤ 10100000 − 1, T组数据的数字的十进制表示长度总和不超过1000000
输出描述:
每行一个整数 m 第 i 行表示第 i 个数所对应的“最邻近二数”
AC代码:
#include<bits/stdc++.h>
#define lson l,mid,t<<1
#define rson mid+1,r,t<<1|1
#define ll long long
using namespace std;
const int maxn=1000010;
const int mo=1e12;
int m,k,x,y;
int cnt,n;
char ans[maxn],tmp[maxn];
int flag;
char s[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%s",s);
int l=strlen(s);
int mi=-1,ma=-1;
for(int i=0;i<l;i++)
{
int id=(s[i]&15);
if(id&1) {mi=i;break;}
tmp[i]=s[i];
ans[i]=s[i];
}
if(mi==-1) {printf("%s\n",s);continue;}
int qian=0;
int hou=0;
if(s[mi]!='9')
{
tmp[mi]=(s[mi]+1);
ans[mi]=(s[mi]-1);
int t=(s[mi]&15)*10;
int f=(tmp[mi]&15)*10;
int g=(ans[mi]&15)*10;
int i=mi+1;
while(i<l)
{
int id=t+(s[i]&15);
if(abs(f-id)>abs(id-g-8)&&!qian&&!hou) {qian=1;}
else if(abs(f-id)<abs(id-g-8)&&!qian&&!hou) {hou=1;}
else {f=(tmp[mi]&15)*10;g=(ans[mi]&15)*10;;}
tmp[i]='0';
ans[i]='8';
i++;
}
}
else
{
qian=1;
ans[mi]=(s[mi]-1);
int i=mi+1;
while(i<l)
{
ans[i]='8';
i++;
}
}
ans[l]='\0';tmp[l]='\0';
if(qian||(qian==0&&hou==0))
{
int i=0;
while(ans[i]=='0'&&i<l-1) i++;
printf("%s\n",ans+i);
}
else
{
int j=0;
while(tmp[j]=='0'&&j<l-1) j++;
printf("%s\n",tmp+j);
}
}
return 0;
}