2020 PAT秋季甲级考试(91分)-记
2020-9-5 刚考完PAT
最后半小时手机居然关机断网了!!!
题目描述可以参考2020年PAT秋原题
第一题(奶牛题)
好坑,我想的是找出单调序列,从小到大依次赋值,序列最大的点先放着,之后根据两边的值确定每个最大点处的值。最后一个点wa(-3分)
code1
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int d[10005];
int main()
{
int N; cin>>N;
int a[N+3];
for(int i=1;i<=N;++i) cin>>a[i];
a[0]=-1; a[N+1]=-1;
//寻找单调序列
for(int i=1;i<N;++i)
{
//寻找单减
int f=1;
int j;
for(j=i;j<N;++j)
{
if(a[j+1]>a[j]) {
break;
}
}
if(j==N) j--;
if(j==i) f=0;//f=0 是单增
if(f==0)
{
for(j=i;j<N;++j)
{
if(a[j+1]<a[j]) break;
}
}
//cout<<j<<" "<<f<<" "<<i<<endl;
if(f)//减
{
int now=200;
for(int k=j;k>i;--k) {
d[k]=now;
if(a[k-1]!=a[k])
now+=100;
}
i=j; //i=j-1修改为i=j
}
else {
int now=200;
for(int k=i;k<j;++k) {
d[k]=now;
if(a[k+1]!=a[k])
now+=100;
}
i=j; //i=j-1修改为i=j
}
}
for(int i=1;i<=N;++i)
{
//cout<<d[i]<<" ";
if(d[i]==0 && i!=1 && i!=N)
{
d[i]=max(d[i-1],d[i+1])+100;
}
}
if(N>1)
if(d[N]==0)
if(a[N]>a[N-1]) d[N]=d[N-1]+100;
else if(a[N]==a[N-1]) d[N]=d[N-1];
if(d[1]==0)
if(a[1]>a[2]) d[1]=d[2]+100;
else d[1]=d[2];
ll ans=0;
for(int i=1;i<=N;++i)
{
ans+=d[i];
//cout<<d[i]<<" ";
}
if(N==1) cout<<"200"<<endl;
else if(N==2) {
if(a[1]!=a[2]) cout<<"500"<<endl;
else cout<<"400"<<endl;
}
else cout<<ans<<endl;
return 0;
}
第二题
区间和问题,先求前缀和,再暴力找(满分)
code2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll N,M;
ll a[10005];
ll total=0;
ll sum[10005];
int main()
{
scanf("%lld%lld",&N,&M);
for(int i=1;i<=N;++i) {
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int i=0;i<N;++i)
for(int j=i+1;j<=N;++j)
if(sum[j]-sum[i]<=M) total++;
printf("%lld\n",total);
return 0;
}
第三题
建树(给出中序,前序)拼题A上做过类似的click(满分)
code3
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int N;
int in[25],pre[25];//中序和先序
int tree[25][3];
void build(int l,int r,int l1,int r1)
{
if(l>r) return ;
int i;
for(i=l1;i<=r1;++i)
if(in[i]==pre[l]) break;
if(i!=l1)//有左孩子
{
tree[l][1]=l+1;
build(l+1,l+i-l1,l1,i-1);
}
if(i!=r1)
{
tree[l][2]=(l+i-l1+1);
build(l+i-l1+1,r,i+1,r1);
}
}
struct node{
int index;
int ceng;
}temp;
int flag[25];//每层标记
int main()
{
cin>>N;
for(int i=1;i<=N;++i) cin>>in[i];
for(int i=1;i<=N;++i) cin>>pre[i];
build(1,N,1,N);
queue<node>Q;
temp.index=1; temp.ceng=1;
Q.push(temp);
while(!Q.empty())
{
temp=Q.front(); Q.pop();
if(flag[temp.ceng]==0) {
if(temp.ceng!=1) printf(" ");
printf("%d",pre[temp.index]);
flag[temp.ceng]=1;
}
if(tree[temp.index][1]!=0)
{
node temp1;
temp1.ceng=temp.ceng+1;
temp1.index=tree[temp.index][1];
Q.push(temp1);
}
if(tree[temp.index][2]!=0)
{
node temp1;
temp1.ceng=temp.ceng+1;
temp1.index=tree[temp.index][2];
Q.push(temp1);
}
}
return 0;
}
第四题(阅读理解题)
环+最短路,我居然不会找环,写了个垃圾算法,TLE了!!(-6分)
题意:给定一个有向图,边权为S、D,存在环则输出impossible,否则输出ok,然后对每个询问,输出一条从入度为0的点到该点的最短路径
code4
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int N,M;
struct node{
int v;
int S,D;
}temp;
vector<node>G1[1006];//反
int S1[1006][1006];
int D1[1006][1006];
int f[1006];//环标记
int flag=0;
int now;
void DFS1(int x,int cnt,vector<int> v)//查找环
{
if(cnt>M) return ;
if(x==now && cnt>1)//环
{
for(int i=0;i<v.size();++i) f[v[i]]=1;
//f[now]=1;
flag=1;
return ;
}
else {
for(int i=0;i<G1[x].size();++i)
{
v.push_back(G1[x][i].v);
DFS1(G1[x][i].v,cnt+1,v);
v.pop_back();
}
}
}
stack<int>ans;
int S_=INT_MAX,D_;
void DFS(int x,stack<int> st,int S_now,int D_now)
{
if(G1[x].size()==0)//选择最优解
{
if(S_now<S_) {
S_=S_now;
D_=D_now;
ans=st;
}
else if(S_now==S_ && D_now>D_)
{
D_=D_now;
ans=st;
}
return ;
}
else
{
for(int i=0;i<G1[x].size();++i)
{
int v=G1[x][i].v;
if(f[v]==0)
{
st.push(v);
DFS(v,st,S_now+S1[v][x],D_now+D1[v][x]);
st.pop();
}
}
}
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=1;i<=M;++i)
{
int T1,T2,S,D;
scanf("%d%d%d%d",&T1,&T2,&S,&D);
S1[T1][T2]=S;
D1[T1][T2]=D;
temp.v=T1; temp.S=S; temp.D=D;
G1[T2].push_back(temp);
}
for(int i=0;i<N;++i)
{
if(f[i]) continue;
now=i;
vector<int> vv;
vv.push_back(i);
DFS1(i,0,vv);
}
if(flag) printf("Impossible.\n");
else printf("Okay.\n");
int Q;
scanf("%d",&Q);
while(Q--)
{
int t; scanf("%d",&t);
if(G1[t].size()==0) {
printf("You may take test %d directly.\n",t);
continue;
}
if(f[t]) {
printf("Error.\n");
continue;
}
S_=INT_MAX;
D_=0;
stack<int>st;
st.push(t);
DFS(t,st,0,0);
while(!ans.empty())
{
int p=ans.top();
ans.pop();
printf("%d",p);
if(ans.size()>0) printf("->");
}
printf("\n");
}
return 0;
}