您的位置:首页 > 其它

西北工业大学省赛选拔!!!

2017-04-30 03:14 288 查看
这次打的超级不好

1.直接上手E题结果那个输入的最后一个是5 1OOOOOOO/9999999 其中是O 而不是0

然后本来可以一血的,结果卡了好久也没过

2 ABC暴力题刚开始没认真读题然后就姿势不对,一直到自己明白题意才过

3 F题当时没几个人过感觉会很难,没做其实是签到题!!!

4 做题太慢导致D题没有好好思考,也就没好好做

A https://vjudge.net/problem/UVALive-7091

B https://vjudge.net/problem/UVALive-7092

C https://vjudge.net/problem/UVALive-7094

D https://vjudge.net/problem/UVALive-7095

E https://vjudge.net/problem/UVALive-7096

F https://vjudge.net/problem/UVALive-7097

A:

读入数据初始化vis数组,push优先队列(权值大的优先)

从大到小站队,用vis数组记录这个还在不在,然后top的下标的后面的人数加起来就是这个人站队需要的次数! 

最后 vis清零该节点 pop,输出ans就行了。

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int num[25];
bool vis[25];
struct node
{
int data;
int ord;
bool friend operator < (const struct node a,const struct node b)
{
return a.data<b.data;
}
};
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
priority_queue<node> que;
int cnt;
struct node u;
scanf("%d",&cnt);
for(int i=1;i<=20;i++)
{
scanf("%d",&u.data);
u.ord=i;
que.push(u);
num[i]=i;
vis[i]=1;
}
int ans=0;
while(!que.empty())
{
u=que.top(); que.pop();
for(int i=u.ord+1;i<=20;i++)
{
ans+=vis[i];
}
vis[u.ord]=0;
}
printf("%d %d\n",cnt,ans);
}
return 0;
}

B:问有几个区间,其中包含的数都大于 左-1和右+1 的值
题意:

暴力枚举起点和终点,模拟即可

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;

int num[16];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int cnt;
scanf("%d",&cnt);

for(int i=1;i<=12;i++)
{
scanf("%d",&num[i]);
}

int ans=0;
for(int i=2;i<=11;i++)
{
for(int j=i;j<=11;j++)
{
bool ssc=1;
for(int k=i;k<=j;k++)
{
if(num[k]<=num[i-1]||num[k]<=num[j+1]) { ssc=0; break;}
}
if(ssc) ans++;
}
}
printf("%d %d\n",cnt,ans);
}
return 0;
}


C:题意判断是否是happ+质数(happy各个位的数值的平方之和 递归如果出现1 则 是happy num)

{

     1.素数用素数筛,微大于O(n)的复杂度  

     2.当时懒得想判断是否有循环,直接循环100次如果没有出现过happy就说明不是happy

}

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=1e5+100;
bool pim[maxn];

void get()
{
memset(pim,1,sizeof(pim));
pim[1]=0;
for(int i=2;i<maxn;i++)
{
if(pim[i])
{
for(int j=2*i;j<maxn;j+=i)
{
pim[j]=0;
}
}
}
}

int getnum(int num)
{
int x=num;
int ans=0;
while(x)
{
int flag=x%10;
ans+=(flag*flag);
x/=10;
}
return ans;
}

bool dfs(int pos,int step)
{
if(step>=100) return 0;
if(pos==1) return 1;
return dfs(getnum(pos),step+1);
}

int main()
{
int T;
scanf("%d",&T);
get();
while(T--)
{
int cnt,num;
scanf("%d %d",&cnt,&num);
if(pim[num]&&dfs(num,0))
{
printf("%d %d YES\n",cnt,num);
}
else
{
printf("%d %d NO\n",cnt,num);
}
}
return 0;
}

D
个人感觉D题是最难的一道题,当时没来得及做



插入当时侍聚聚手推过程。我也是赛后看他的代码才明白是什么规律。

预处理答案即可

{

      1.将i-1的长度和值全部都塞给i;

      2.扫一遍{

                         ->1. 如果是大于0的数 ,--即可

->2.如果第j个位置是0的话,改成j ,结束循环

     }

      3.如果每个数值都大于0,将len[i]++;然后 ans[k][len[i]]=len[i];

      4.输出每十个换一次行,为了这个pe了一发

}

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int ans[2010][85];
int len[2010];
int main ()
{
memset(ans,0,sizeof(ans));
memset(len,0,sizeof(len));
len[0]=1;
for(int i=1;i<=2000;i++)
{
len[i]=len[i-1];
for(int j=1;j<=len[i];j++)
{
ans[i][j]=ans[i-1][j];
}
for(int j=1;j<=len[i];j++)
{
if(ans[i][j])
{
ans[i][j]--;
}
else
{
ans[i][j]=j;break;
}
}
if(ans[i][len[i]]==len[i]-1) { len[i]++; ans[i][len[i]]=len[i] ;}
}
int t;
scanf("%d",&t);
while(t--)
{
int cnt,k;
scanf("%d%d",&cnt,&k);
printf("%d %d\n",cnt,len[k]);
int tt=0;
for(int i=1;i<=len[k];i++)
{
++tt;
printf("%d",ans[k][i]);
if(tt==10)
{
printf("\n");tt=0;
}
else if(i!=len[k]) printf(" ");
}
if(len[k]%10) printf("\n");
}
return 0;
}


E题真是血崩。
题意  父亲节点为p/q ,左儿子 p/(p+q) 右儿子 (p+q)/q; 给一点求它的下一个点

做法

{    

      讨论即可

     1.当 q==1 的时候 输出 1/p+1;

     2.当p<q 的时候  输出 q/q-p;

     3. 当p>q 递归向上until  p<q(同时记录递归了多少层)再求记录层数的左子树即可

}

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
void work(int cnt,long long p,long long q)
{
if(q==1)
{
printf("%d %lld/%lld\n",cnt,q,p+1);
return;
}
else if(p<q)
{
printf("%d %lld/%lld\n",cnt,q,q-p);
return;
}
else
{
long long pp=p,qq=q;
long long step=0;
while(1)
{
if(pp<qq) break;
pp=pp-qq;
step++;
}
long long x,y;
x=pp; y=qq;
pp=y;
qq=y-x;
while(1)
{
if(step==0) break;
pp=pp;
qq=pp+qq;
step--;
}
printf("%d %lld/%lld\n",cnt,pp,qq);
}
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int cnt;
long long p=0,q=0;
scanf("%d %d/%d",&cnt,&p,&q);
work(cnt,p,q);
}
return 0;
}

//5 1/1OOOOOOO


F 其实是个大水题。后悔啊。
 只有正号 讨论x,y的大小就可以了。

 x<y 2步 否则6步即可;

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int ax[25];
int ay[25];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int tt,x,y;
scanf("%d%d%d",&tt,&x,&y);
if(x<y)
{
printf("%d %d %d %d\n",tt,2,x,y);
}
else
{
if(x+2<=x-y+5) printf("%d NO PATH\n",tt);
else printf("%d %d %d %d %d %d %d %d\n",tt,6,1,2,3,x-y+5,x+2,x+3);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: