浙大PAT考试1009~1012(1010是个神题。。)

哎,pat1010居然用java写的,不仅用java写的,还加了二分,,,唉,智商捉急啊,主要是pat有的范围也不给清楚。给人造成遐想的空间。。



还是按顺序介绍。。


题目地址:点击打开链接



1009:

题目大意:模拟多项式相乘的,比如(5x^3+4x)*(4x^2+6)这样的,直接用数组存储就好,反正最多1000+1000=2000项

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=2005;

double a[maxn],b[maxn];
double ans[maxn];

int res1[maxn];
double res2[maxn];

int main()
{
    int n,i,j;

    int x;
    double ax;
    while(cin>>n)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(ans,0,sizeof(ans));
        for(i=0;i<n;i++)
        {
            cin>>x>>ax;
            a[x]=ax;
        }
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>x>>ax;
            b[x]=ax;
        }

        for(i=0;i<=1000;i++)
        {
            for(j=0;j<=1000;j++)
            {
                ans[i+j]+=a[i]*b[j];
            }
        }

        int t=0;
        for(i=2000;i>=0;i--)
        {
            if(fabs(ans[i])>=0.1)
            {
                t;
                res1[t]=i;
                res2[t++]=ans[i];
            }
        }

        cout<<t;
        for(i=0;i<t;i++)
            printf(" %d %.1f",res1[i],res2[i]);
        cout<<endl;
    }
    return 0;
}

/*
2 1 2.4 0 3.2
2 2 1.5 1 0.5
*/


1010:

题目大意:给你n1,n2,flag,p四个数字,如果flag是1的话,那么n1是p进制的数字,那么我们能否找到一个数k,使得n2是k进制,使得n1(p)==n2(k),如果存在多个k,找最小的k,如果一个也不存在,那么直接输出Impossible,如果flag是2,我们需要找的是n2(p)==n1(k),其他都一样。

解题思路:这个题目我WA了15次以上。。最开始觉得0-9,a-z最多不超过36进制,算了一下,用long long 写了一发,分数只能拿12分/25分,到最后才想起来可能有这样的数据:

zzzzzzzzz zzzzzzzzz 1 1000

然后把枚举进制的范围扩大到1000,发现可以拿24分了,但是发现再开大就会爆内存,后来想了一下,会有这样的数据:

zzzzzzzzz zzzzzzzzz 1 10000000000

最后很果断的选择了java的大数类和二分来找答案。

这题真的很不容易。。。。


AC代码:

//package xixi;
import java.util.*;

import java.math.*;

public class Main {
	public static void main(String args[])
	{
		String s1,s2,s3;
		
		BigInteger ans,ss,n;
		int flag;
		Scanner cin = new Scanner(System.in);
		while(cin.hasNext())
		{
			s1=cin.next();
			s2=cin.next();
			flag=cin.nextInt();
			n=cin.nextBigInteger();
			if(flag==2)
			{
				s3=s1;
				s1=s2;
				s2=s3;
			}
			
			int len=s1.length();
		    ans=BigInteger.ZERO;
		    for(int i=0; i<=len-1; i++)
		    {
		        int tmp;
		        if(s1.charAt(i)>='a'&&s1.charAt(i)<='z') tmp=s1.charAt(i)-'a'+10;
		        else tmp=s1.charAt(i)-'0';
		        ans=ans.multiply(n).add(BigInteger.valueOf(tmp));
		    }
		    
		    //System.out.println(ans);
		    BigInteger res=BigInteger.ZERO;
		    
		    int t;
		    len=s2.length();

		    String pp="100000000000000000000";  //10^20
		    BigInteger l,mid;
		    l=BigInteger.ONE;
		    BigInteger r=new BigInteger(pp);
		    
		    
		    while(r.compareTo(l)>=0)  
		    {
		        ss=BigInteger.ZERO;
		        
		        mid=l.add(r).divide(BigInteger.valueOf(2));
		        int fla=0;
			    for(int i=0; i<=len-1; i++)
			    {
			        int tmp;
			        if(s2.charAt(i)>='a'&&s2.charAt(i)<='z') tmp=s2.charAt(i)-'a'+10;
			        else tmp=s2.charAt(i)-'0';
			  
			        if(BigInteger.valueOf(tmp).compareTo(mid)>=0)
		            {
		                fla=1;
		                break;
		            }
			        ss=ss.multiply(mid).add(BigInteger.valueOf(tmp));
		        }
			    
		        if(fla==1) 
		        {
		        	l=mid.add(BigInteger.ONE);
		        }
		        if(ss.compareTo(ans)==0)
		        {
		        	res=mid;
		        	r=mid.add(BigInteger.valueOf(-1));
		        }
		        else if(ss.compareTo(ans)>0)
		        {
		        	r=mid.add(BigInteger.valueOf(-1));
		        }
		        else 
		        {
		        	l=mid.add(BigInteger.ONE);
		        }
		    }
		    
		    if(res.compareTo(BigInteger.ZERO)>0) System.out.println(res);
		    else System.out.println("Impossible");
		}

	}
}

/*
6 110 1 10
1 ab 1 2
110 6 1 2
zzzzzzzzz zzzzzzzzz 1 10000000000
*/



1011:

题目大意:20分的题目,直接看例子就可以了,找三行里面每行最大的数,然后标记,然后计算就可以了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const double eps=1e-12;

char mp[3]= {'W','T','L'};
char ans[3];

struct node
{
    double x;
    int index;
}nod[3];

int cmp(node p1,node p2)
{
    if(p1.x>p2.x) return 1;
    return 0;
}

int main()
{
    double res;
    int i;

    while(cin>>nod[0].x>>nod[1].x>>nod[2].x)
    {
        int t=0;
        res=1.0;
        for(i=0; i<3; i++)
            nod[i].index=i;
        sort(nod,nod+3,cmp);
        res=res*nod[0].x;
        ans[t++]=mp[nod[0].index];

        int xy=2;
        while(xy--)
        {
            cin>>nod[0].x>>nod[1].x>>nod[2].x;
            for(i=0; i<3; i++)
                nod[i].index=i;
            sort(nod,nod+3,cmp);
            res=res*nod[0].x;
            ans[t++]=mp[nod[0].index];
        }

        res=(res*0.65-1)*2;

        double res1=res*100;

        /*cout<<res1<<endl;
        if(res1-int(res1)>=0.5)
        {
            res1=res1+1;
        }
        res=res1/100.0;*/
        printf("%c %c %c %.2f\n",ans[0],ans[1],ans[2],res+eps);
        //不加这个eps硬是少一点。。
    }
    return 0;
}

/*
1.1 2.5 1.7
1.2 3.0 1.6
4.1 1.2 1.1
*/


1012:

题目大意:给一个班所有学生的成绩,包括C,M,E三种成绩,当然我们可以算出他的A成绩,然后我们每次根据学号来查询一个人的成绩排名,四种成绩会有四种排名,我们需要最靠前的排名,如果有相同的,按照A > C > M > E的顺序即可。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<map>
#define ll long long
using namespace std;
const int maxn=2005;

map<string,int> mp;
struct node
{
    double a;
    double c;
    double m;
    double e;
}nod[maxn];

int main()
{
    int n,m,i,j;

    while(cin>>n>>m)
    {
        string s;
        double mc,mm,me;
        for(i=1;i<=n;i++)
        {
            cin>>s>>mc>>mm>>me;
            nod[i].a=(mc+mm+me)/3.0;
            nod[i].c=mc,nod[i].e=me,nod[i].m=mm;
            mp[s]=i;
        }

        for(i=0;i<m;i++)
        {
            int rank1=n+1;
            char res;
            cin>>s;
            if(!mp[s])
            {
                puts("N/A");
                continue;
            }

            //原谅我把一段代码复制了四遍。。。
            double tmp=nod[mp[s]].a;   //A
            int cnt=1;
            for(j=1;j<=n;j++)
            {
                //cout<<nod[j].a<<endl;
                if(nod[j].a>tmp)
                    cnt++;
            }
            if(cnt<rank1)
            {
                rank1=cnt;
                res='A';
            }

            //cout<<rank1<<endl;

            tmp=nod[mp[s]].c;   //C
            cnt=1;
            for(j=1;j<=n;j++)
            {
                if(nod[j].c>tmp)
                    cnt++;
            }
            if(cnt<rank1)
            {
                rank1=cnt;
                res='C';
            }

            tmp=nod[mp[s]].m;   //M
            cnt=1;
            for(j=1;j<=n;j++)
            {
                if(nod[j].m>tmp)
                    cnt++;
            }
            if(cnt<rank1)
            {
                rank1=cnt;
                res='M';
            }

            tmp=nod[mp[s]].e;   //E
            cnt=1;
            for(j=1;j<=n;j++)
            {
                if(nod[j].e>tmp)
                    cnt++;
            }
            if(cnt<rank1)
            {
                rank1=cnt;
                res='E';
            }

            printf("%d %c\n",rank1,res);
        }
    }
    return 0;
}

/*
5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999
*/

世界杯今日开战,mark一下!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值