您的位置:首页 > 其它

寒假训练3

2018-02-20 08:41 148 查看

51nod 1004 n^n的末位数字

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1004

就是个快速幂嘛

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
int ksm(int a,int b){
a%=10;
int ans=1;
while(b){
if(b&1)
ans=(ans*a)%10;
b>>=1;
a=(a*a)%10;
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",ksm(n,n));
}


51nod 1489 蜥蜴和地下室

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1489

诡异的是生命值小于0才会死而不是小于等于,没事,我们都加个1就行了

注意到N特别小:10,生命值也最高15

定义d(i,j,k,r)为前i个都已经死了,i+1个生命为j,i+2个生命为k,i+3个生命为r,且不存在或<0都按0算

那么,我们就可以来枚举在哪里放火球来我为人人地递推,注意不能直接作用于最后一个,需要特判

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int N=20,H=16;
int h
;
int d

;
int main()
{
int n,a,b;
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++){
scanf("%d",&h[i]);
h[i]++;
}
memset(d,-1,sizeof d);
int t=h[1]/b+(h[1]%b!=0);
int p2=h[2]-a*t;
int p3=h[3]-b*t;
if(p2<0)
p2=0;
if(p3<0)
p3=0;
d[1][p2][p3][h[4]]=t;
for(int i=1;i<=n-2;i++){
for(int j=H;j>=0;j--)
for(int k=H;k>=0;k--)
for(int r=H;r>=0;r--){
if(d[i][j][k][r]==-1)
continue ;
int jj=j-a,kk=k-b,rr;
if(jj<0) jj=0;
if(kk<0) kk=0;
if(d[i][jj][kk][r]==-1||d[i][jj][kk][r]>d[i][j][k][r]+1)
d[i][jj][kk][r]=d[i][j][k][r]+1;
if(i==n-2)
continue ;
jj=j-b,kk=k-a,rr=r-b;
if(jj<0) jj=0;
if(kk<0) kk=0;
if(rr<0) rr=0;
if(d[i][jj][kk][rr]==-1||d[i][jj][kk][rr]>d[i][j][k][r]+1)
d[i][jj][kk][rr]=d[i][j][k][r]+1;
}
for(int j=H;j>=0;j--)
for(int k=H;k>=0;k--)
d[i+1][j][k][h[i+4]]=d[i][0][j][k];
}
int ans=d[n-2][0][0][0];
printf("%d\n",ans);
}


51nod 1280 前缀后缀集合

乍一看,没啥思路,先做后面的题去了

数据范围限制下,应该只能O(N)或O(NlogN)了

NlogN:排序?二分?或者说,map?

那就map了,理论上来说应该是O(NlogN)的吧

所以其实主要就是一个基于map的暴力

哦,对了,还有long long…

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int N=50010;
long long ans=0;
map<int,int>p;
map<int,int>p1;
int a
,b
;
int Read(){
int res=0;
char c;
while(1){
c=getchar();
if(c>='0'&&c<='9'){
res=res*10+c-'0';
}
else
return res;
}
}
int main()
{
int n;
n=Read();
for(int i=1;i<=n;i++){
a[i]=Read();
b[n-i+1]=a[i];
int x=p1[a[i]];
if(x==0||x>n-i+1)
p1[a[i]]=n-i+1;
}
int last=0,j=1;
for(int i=1;i<=n;i++){
p[a[i]]=1;
last=max(last,p1[a[i]]);
for(;j<=n;j++)
if(p[b[j]]==0)
break;
if(j>last)
ans+=j-last;
}
printf("%lld\n",ans);
}


51nod 1281 山峰和旗子

额,大水题

O(N)先扫一遍,找出所有山峰

然后就成了一道二分答案的版题

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int N=50010;
int h
;
int p
,pcnt;
bool check(int x){
int sum=0,past=-1;
for(int i=1;i<=pcnt;i++)
if(past==-1||p[i]-past>=x){
sum++;
past=p[i];
}
return sum>=x;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
for(int i=2;i<=n-1;i++)
if(h[i-1]<h[i]&&h[i]>h[i+1])
p[++pcnt]=i;
int l=0,r=pcnt+1;
while(l+1<r){
int mid=(l+r)>>1;
if(check(mid))
l=mid;
else
r=mid;
}
printf("%d\n",l);
}


51nod 1055 最长等差数列

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1055

本着暴力或许能过的想法码了一发

看错题啦!!!

自行脑补了一个必须是它给出序列的子序列

然后WA了好久

额,然而

最后TLE了

因为自己其实想法有点问题

忽视了等差中项的应用

不过这个忽视主要是因为一开始想的是子序列,那就只有枚举两个起始点

还有short卡内存…

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int N=10010;
int a
;
short d

;
int Read(){
int res=0;
char c;
while(1){
c=getchar();
if(c>='0'&&c<='9'){
res=res*10+c-'0';
}
else
return res;
}
}
int main()
{
int n;
n=Read();
for(int i=1;i<=n;i++){
a[i]=Read();
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
d[i][j]=2;
int ans=2;
for(int j=2;j<n;j++){
int i=j-1,k=j+1;
while(i>0&&k<=n){
if(a[i]+a[k]<2*a[j])
k++;
else if(a[i]+a[k]>2*a[j])
i--;
else{
d[j][k]=d[i][j]+1;
if(d[j][k]>ans)
ans=d[j][k];
i--,k++;
}
}
}
printf("%d\n",ans);
}


51nod 1424 零树

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1424

总的来说,

又是

看错题了

一开始想的算法差不多就是最后实现的算法

只是中途一不小心就看错题,然后推翻了之前的做法…

而且还被longlong坑了一次

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
const int N=100010;
long long val
,fsum
,zsum
,mf
,mz
;
vector<int>edge
;
bool vis
;
void dfs(int u){
vis[u]=1;
for(int i=0;i<(int)edge[u].size();i++){
int v=edge[u][i];
if(vis[v])
continue ;
dfs(v);
mf[u]=max(fsum[v],mf[u]);
mz[u]=max(zsum[v],mz[u]);
}
val[u]-=mf[u];
val[u]+=mz[u];
zsum[u]=mz[u];
fsum[u]=mf[u];
if(val[u]<0){
zsum[u]+=-val[u];
}
else{
fsum[u]+=val[u];
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
edge[u].push_back(make_pair(u,v));
edge[v].push_back(make_pair(v,u));
}
for(int i=1;i<=n;i++)
scanf("%lld",&val[i]);
dfs(1);
long long ans=fsum[1]+zsum[1];
printf("%lld\n",ans);
}


51nod 1792 Jabby’s segment tree

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1792

//考场上并没有什么思路
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: