去年的比赛了
昨天浏览山理的官网,偶然看到的
有一说一,山理对算法竞赛的重视程度确实高
别人学校的OJ真的好
唉。。。
注册了账号,当成模拟赛打了一把,自闭。。。
A题
签到题
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
if(b%2!=0)
{
if(a%2!=0)
{
cout<<"black"<<endl;}
else
{
cout<<"white"<<endl;}
}
else
{
if(a%2==0)
{
cout<<"black"<<endl;}
else
{
cout<<"white"<<endl;}
}
return 0;
}
B题
签到题
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[10];
int main()
{
for(int i=0;i<5;i++)
{
cin>>a[i];
}
sort(a,a+5);
cout<<a[0]+a[1]+a[2]+a[3]<<" "<<a[1]+a[2]+a[3]+a[4]<<endl;
return 0;
}
C题
签到题
#include <bits/stdc++.h>
#define ll long long
using namespace std;
string s="SDUTACM";
int main()
{
int n;
cin>>n;
int k=0;
for(int i=1;i<=n;i++)
{
if(i==1||i==n)
{
for(int j=1;j<=n;j++)
{
cout<<s[k];
k++;k%=7;
}
cout<<endl;
}
else
{
cout<<s[k];k++;k%=7;
for(int i=1;i<=n-2;i++)
{
cout<<" ";}
cout<<s[k]<<endl;k++;k%=7;
}
}
return 0;
}
E题
递归题,按照题意写个递归即可
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[100];
void down(int x);
void up(int x);
void down(int x)
{
if(a[x]==0){
return;}
if(x==1)
{
a[1]=0;cout<<"1 DOWN"<<endl;return;}
for(int j=x-1;j>=1;j--)
{
if(j==x-1)
{
if(a[j]==0)
{
up(j);}
}
else
{
if(a[j]==1)
{
down(j);}
}
}
a[x]=0;cout<<x<<" DOWN"<<endl;
}
void up(int x)
{
if(a[x]==1){
return;}
if(x==1)
{
a[1]=1;cout<<"1 UP"<<endl;return;}
for(int j=x-1;j>=1;j--)
{
if(j==x-1)
{
if(a[j]==0)
{
up(j);}
}
else
{
if(a[j]==1)
{
down(j);}
}
}
a[x]=1;cout<<x<<" UP"<<endl;
}
int main()
{
for(int i=1;i<100;i++)
{
a[i]=1;}
int n;
cin>>n;
if(n==1)
{
cout<<"1 DOWN"<<endl;return 0;}
for(int i=n;i>=1;i--)
{
down(i);
}
return 0;
}
F题
最开始想的是扩欧,但扩欧写到一半就写不下去了,太tm难写了,然后换成bfs搜索过了。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
ll w,cnt,time;
};
queue<node>q;
ll vis[100005];
ll flag,lpl,ans;
void bfs(ll a,ll b,ll n,ll m)
{
node e;
e.w=1;
e.cnt=0;
vis[1]=lpl;
q.push(e);
while(!q.empty())
{
node r=q.front();q.pop();
node ee;
ee.w=r.w+a;
ee.cnt=r.cnt+1;
if(ee.w>n)
{
ee.w-=n;}
if(ee.w==m)
{
flag=1;ans=ee.cnt;return;}
if(vis[ee.w]!=lpl)
{
vis[ee.w]=lpl;
q.push(ee);
}
/
node u;
u.w=r.w+b;
u.cnt=r.cnt+1;
if(u.w>n)
{
u.w-=n;}
if(u.w==m)
{
flag=1;ans=u.cnt;return;}
if(vis[u.w]!=lpl)
{
vis[u.w]=lpl;
q.push(u);
}
}
}
void init()
{
while(!q.empty())
{
q.pop();}
}
int main()
{
ll t,n,m,a,b;
cin>>t;
while(t--)
{
init();
lpl++;
flag=0;ans=0;
cin>>n>>m;
cin>>a>>b;
if(m==1)
{
cout<<"YES"<<endl<<"0"<<endl;continue;}
bfs(a,b,n,m);
if(flag==0)
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
cout<<ans<<endl;
}
}
return 0;
}
G题
排序+贪心
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a[100005];
ll vis[100005];
struct node
{
ll w,id;
}q[100005];
bool cmp(node a,node b)
{
if(a.w>b.w)
{
return 1;}
if(a.w==b.w)
{
if(a.id>b.id)
{
return 1;}
return 0;
}
return 0;
}
int main()
{
ll n,x,y;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x>>y;
a[i]=x+y;
q[i].w=a[i];
q[i].id=i;
}
sort(q+1,q+1+n,cmp);
ll st=1,ans=0;
for(int i=1;i<=n;i++)
{
if(vis[q[i].id]==0)
{
ll op=0,cnt=0;
while(st<q[i].id)
{
vis[st]=1;
op+=a[st];
cnt++;
st++;
}
vis[st]=1;
ans+=cnt*a[st]-op;
st++;
}
}
cout<<ans<<endl;
return 0;
}
H题
一开始用线段树超时了,这道题是看了题解才过的(丢人),否则我真没发现一个数进行若干次Xh(x)操作后会变成13且不再变化。。。。傻乎乎的我还推了半天公式。。。。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
ll l,r,pre;
ll flg;
}sum[1000006];
ll a[1000006],oo=1;
ll digit(ll x)
{
ll ans=0;
while(x>0)
{
ans+=x%10;
x/=10;}
return ans;
}
void build(ll l,ll r,ll os)
{
sum[os].l=l;
sum[os].r=r;
if(l==r)
{
sum[os].pre=a[oo++];
if(sum[os].pre==13){
sum[os].flg=1;}
return;
}
ll mid=(l+r)/2;
build(l,mid,os*2);
build(mid+1,r,os*2+1);
sum[os].pre=sum[os*2].pre+sum[os*2+1].pre;
sum[os].flg=(sum[os*2].flg)&(sum[os*2+1].flg);
}
void change(ll x,ll y,ll os)
{
if(x<=sum[os].l&&y>=sum[os].r)
{
if(sum[os].flg==1)
{
return;}
if(sum[os].l==sum[os].r)
{
sum[os].pre=3*digit(sum[os].pre)+1;
if(sum[os].pre==13){
sum[os].flg=1;}
return;
}
}
ll mid=(sum[os].l+sum[os].r)/2;
if(x<=mid)
{
change(x,y,os*2);}
if(y>mid)
{
change(x,y,os*2+1);}
sum[os].pre=sum[os*2].pre+sum[os*2+1].pre;
sum[os].flg=(sum[os*2].flg)&(sum[os*2+1].flg);
}
ll query(ll x,ll y,ll os)
{
if(x<=sum[os].l&&y>=sum[os].r)
{
return sum[os].pre;}
ll ans=0;
ll mid=(sum[os].l+sum[os].r)/2;
if(x<=mid)
{
ans+=query(x,y,os*2);}
if(y>mid)
{
ans+=query(x,y,os*2+1);}
return ans;
}
int main()
{
ll n,m,l,r,op;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);}
build(1,n,1);
scanf("%lld",&m);
while(m--)
{
scanf("%lld %lld %lld",&op,&l,&r);
if(op==2)
{
change(l,r,1);
}
if(op==1)
{
printf("%lld\n",query(l,r,1));
}
}
return 0;
}
J题
数据小,暴力即可
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
//double pi=acos(-1);
ll vis[10000];
int main()
{
ll n,m;
char s[100][505];
scanf("%lld %lld",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);}
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
ll cnt=0;
for(int k=0;k<m;k++)
{
if(s[i][k]=='1'||s[j][k]=='1')
{
cnt++;}
}
vis[cnt]++;
}
}
for(ll i=999;i>=0;i--)
{
if(vis[i]>0)
{
printf("%lld\n",i);
printf("%lld\n",vis[i]);
break;
}
}
return 0;
}
K题
签到题
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
double pi=acos(-1);
int main()
{
double a,b;
cin>>a>>b;
double cr=pi*(a*a+b*b)/4.0;
double ans=cr-a*b;
printf("%.3lf\n",ans);
return 0;
}
自身水平还是不行啊