pta 1007-1009

1007 素数对猜想 (20 分)

题目:

让我们定义dn​为:dn​=pn+1​−pn​,其中pi​是第i个素数。显然有d1​=1,且对于n>1有dn​是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N(<105),请计算不超过N的满足猜想的素数对的个数。

输入格式:

输入在一行给出正整数N

输出格式:

在一行中输出不超过N的满足猜想的素数对的个数。

输入样例:

20

输出样例:

4

我的解答:

语言:Java

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int[] primes=new int[n];
        int j=0;
        int count=0;
        for(int i=1;i<=n;i+2){
            if(isPrime(i)){
                primes[j++]=i;
            }
        }
        for(int i=0;i<j-1;i++){
            int d=primes[i+1]-primes[i];
            if(d==2){
                count++;
            }
        }
        System.out.println(count);
    }
    public static boolean isPrime(int n){
        if(n<=2){
            return false;
        }
        for(int j=2;j<=Math.sqrt(n);j++){
            if(n%j==0){
                return false;
            }
        }
        return true;
    }
}

 思路:先把小于n的素数按顺序收集到一个数组(偶数除了2不可能是素数,2和3和5都不是差2,所以直接跳过就行),用一个变量计数,遍历数组逐个判断是否满足条件(两个数直接如果隔一个数是不可能差2的,因为奇数之间肯定是偶数)。

1008 数组元素循环右移问题 (20 分)

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0​A1​⋯AN−1​)变换为(AN−M​⋯AN−1​A0​A1​⋯AN−M−1​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。

输出格式:

在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4

 我的解答(Java):

import java.util.*;
class Main{
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n=s.nextInt();
        int m=s.nextInt();
        int i,j;
        int k;
        int[] a=new int[n];
        for(i=0;i<n;i++){
            a[i]=s.nextInt();
        }
        for(j=0;j<m;j++){
            k=a[n-1];
            for(i=n-1;i>0;i--)
            {
                a[i]=a[i-1];
            }
            a[0]=k;
        }
        for(i=0;i<n;i++)    
        {
            if(i==n-1) System.out.println(a[i]);
            else System.out.print(a[i]+" ");
    }    
    }
}

把输入的数字放进一个数组,遍历数组,每次将数组最后一个元素存在临时变量中,将其他元素依次后移,然后将临时变量的值赋给第一个元素,即每次循环将数组循环右移一位。

1009 说反话 (20 分)

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子。

输入样例:

Hello World Here I Come

输出样例:

Come I Here World Hello

我的解答(Java):

import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
        String st=s.nextLine();
		String[] arr = st.split(" ");
		for (int i = arr.length - 1; i >= 0; i--) {
            if(i==0) System.out.println(arr[i]);
            else System.out.print(arr[i]+" ");
		}
	}
}

 思路:Java中字符串自带函数split(),即按什么标志字符串分开目标字符串,得到的字符串段组成一个字符串数组,这里可以按空格分开,即可得到每个单词,倒序遍历输出即可。

1005 Spell It Right (20 分)

Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output every digit of the sum in English.

Input Specification:

Each input file contains one test case. Each case occupies one line which contains an N (≤10100).

Output Specification:

For each test case, output in one line the digits of the sum in English words. There must be one space between two consecutive words, but no extra space at the end of a line.

Sample Input:

12345

Sample Output:

one five

百度翻译: 

给定一个非负整数N,您的任务是计算N的所有数字的和,并用英语输出和的每个数字。
输入规格:
每个输入文件包含一个测试用例。每个案例占用一行,其中包含一个N(≤10100).
输出规格:
对于每个测试用例,在一行中以英语单词输出总和的数字。两个连续的单词之间必须有一个空格,但行尾不能有额外的空格。

我的解答(Java):

import java.util.Scanner;
class Main{
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String s=scanner.nextLine();
        String[] arr=new String[]{"zero","one","two","three","four","five","six","seven",
"eight","nine"};
        int len=s.length();
        int n=0;
        for (int i=0;i<len;i++){
            n=n+Integer.parseInt(s.substring(i,i+1));
        }
        s=n+"";
        for (int i=0;i<s.length();i++){
            if(i!=s.length()-1){
                System.out.print(arr[Integer.parseInt(s.substring(i,i+1))]+" ");
            }else{
                System.out.print(arr[Integer.parseInt(s.substring(i,i+1))]);
            }
        }
        System.out.println();
    }
}

思路:把索引值对应的英文存到一个数组中,得出各位之和之后遍历字符串,通过字符串向整型的转化输出和的各位。

1008 Elevator (20 分)

The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.

For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.

Input Specification:

Each input file contains one test case. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100.

Output Specification:

For each test case, print the total time on a single line.

Sample Input:

3 2 3 1

Sample Output:

41

这个看懂题是关键,百度翻译: 

我们城市最高的建筑物只有一部电梯。请求列表由N个正数组成。这些数字表示电梯将按指定顺序停在哪个楼层。将电梯向上移动一层需要6秒,向下移动一层需要4秒。电梯在每一站停留5秒钟。
对于给定的请求列表,您需要计算完成列表上的请求所花费的总时间。电梯开始时位于第0层,满足要求后无需返回底层。
输入规格:
每个输入文件包含一个测试用例。每个案例都包含一个正整数N,后跟N个正数。输入中的所有数字都小于100。
输出规格:
对于每个测试用例,在单行上打印总时间。

我的解答(Java):

import java.util.*;
class Main{
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n=s.nextInt();
        int[] arr=new int[n];
        for (int i=0;i<n;i++){
            arr[i]=s.nextInt();
        }
        int count=0;
        for (int i=0;i<n;i++){
            count+=5;
            if (i==0){
                count+=6*(arr[0]);
            }else {
                if (arr[i]>arr[i-1]){
                    count+=6*(arr[i]-arr[i-1]);
                }else {
                    count+=4*(arr[i-1]-arr[i]);
                }
            }
        }
        System.out.println(count);
    }
}

把输入的楼层放进数组,遍历数组通过条件语句算出总数即可。 

1001 Battle Over Cities - Hard Version (35 分)

It is vitally important to have all the cities connected by highways in a war. If a city is conquered by the enemy, all the highways from/toward that city will be closed. To keep the rest of the cities connected, we must repair some highways with the minimum cost. On the other hand, if losing a city will cost us too much to rebuild the connection, we must pay more attention to that city.

Given the map of cities which have all the destroyed and remaining highways marked, you are supposed to point out the city to which we must pay the most attention.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N (≤500), and M, which are the total number of cities, and the number of highways, respectively. Then M lines follow, each describes a highway by 4 integers: City1 City2 Cost Status where City1 and City2 are the numbers of the cities the highway connects (the cities are numbered from 1 to N), Cost is the effort taken to repair that highway if necessary, and Status is either 0, meaning that highway is destroyed, or 1, meaning that highway is in use.

Note: It is guaranteed that the whole country was connected before the war.

Output Specification:

For each test case, just print in a line the city we must protest the most, that is, it will take us the maximum effort to rebuild the connection if that city is conquered by the enemy.

In case there is more than one city to be printed, output them in increasing order of the city numbers, separated by one space, but no extra space at the end of the line. In case there is no need to repair any highway at all, simply output 0.

Sample Input 1:

4 5
1 2 1 1
1 3 1 1
2 3 1 0
2 4 1 1
3 4 1 0

Sample Output 1:

1 2

Sample Input 2:

4 5
1 2 1 1
1 3 1 1
2 3 1 0
2 4 1 1
3 4 2 1

Sample Output 2:

0

百度翻译:

1001城市之战-硬版(35分)
在战争中,让所有城市通过高速公路连接起来是至关重要的。如果一座城市被敌人征服,所有进出该城市的公路都将被关闭。为了保持其余城市的连接,我们必须以最低的成本修复一些高速公路。另一方面,如果失去一座城市会让我们付出太多的代价来重建连接,我们必须更加关注这座城市。
在地图上标出了所有被摧毁和残存的公路,你应该指出我们必须最关注的城市。
输入规格:
每个输入文件包含一个测试用例。每个案例都从一行开始,其中包含2个数字N(≤500)和M,分别为城市总数和公路数量。然后M行跟随,每行用4个整数描述一条公路:City1 City2成本状态,其中City1和City2是公路连接的城市编号(城市编号从1到N),成本是必要时修复公路所付出的努力,状态为0,表示公路被破坏,或1,这意味着公路正在使用中。
注:保证战前全国联网。
输出规格:
对于每个测试用例,只需在一行中打印我们必须抗议最多的城市,也就是说,如果该城市被敌人征服,我们将尽最大努力重建连接。
如果要打印的城市不止一个,请按城市编号的递增顺序输出,并用一个空格分隔,但在行尾不能有额外的空格。如果根本不需要修复任何公路,只需输出0。

我不会,搜出来的答案,详情见1001. Battle Over Cities - Hard Version (35)_lemnHacker的专栏-CSDN博客,下面也是这位博主的代码(C++):

#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
#define N 501
#define INF 0x7fffffff
typedef struct{
int c1;
int c2;
int cost;
}Len;
bool cmp(Len a,Len b)
{
return a.cost<b.cost;
}


vector<Len> lens1,lens2;//lens1废弃的轨道集,lens2在用的轨道集
int root[N];
int findroot(int id)
{
if(root[id]==-1)//本节点就是根节点
return id;
int x=findroot(root[id]);//本语句的原因,两个连通图S1(根节点r1)、S2(根节点r2)合并,
//只是将r2的根节点设为r1,所以当S1,S2合并后,S2中的节点的根节点并未修改,
//当求S2中节点的根节点时,需要先找到r2,再通过r2找到r1
root[id]=x;//及时修改以上情况下S2中节点的根节点为人r1
return x;
}


vector<int> answerids;//存放结果
int maxcost=0;//当前修复代价的最大值
int main()
{
int n,m;
cin>>n>>m;
int c1,c2,cost,tag;
for(int i=0;i<m;++i)
{
cin>>c1>>c2>>cost>>tag;
//len[c1][c2]=len[c2][c1]=cost;
Len tmp;
tmp.c1=c1,tmp.c2=c2,tmp.cost=cost;
if(tag==0)
{
lens1.push_back(tmp);    //tag=0的边集
}
else{
lens2.push_back(tmp);   //tag=1的边集
}
}
sort(lens1.begin(),lens1.end(),cmp);//tag=0的边集排序
for(int i=1;i<=n;++i)  //当去掉i节点后,依据边集进行划分,划分成簇
{
for(int j=1;j<=n;++j)
root[j]=-1;
for(int k=0;k<lens2.size();++k)
{
if(lens2[k].c1==i||lens2[k].c2==i)
continue;
int c1=lens2[k].c1,c2=lens2[k].c2;
int root1=findroot(c1);
int root2=findroot(c2);
if(root1!=root2)
{
root[root2]=root1;
}
}
int cost=0;//删除本节点i后,修复所需要的代价
int num=0; //删除城市i后,彼此连通的城市集合个数,即簇个数
for(int s=1;s<=n;++s)//簇个数
{
if(s!=i&&root[s]==-1)
++num;
}
for(int t=0;t<lens1.size();++t)
{
if(num==1)   //城市簇只有一个,连通
break;
int c1=lens1[t].c1,c2=lens1[t].c2;
if(c1==i||c2==i)
continue;
int root1=findroot(c1);
int root2=findroot(c2);
if(root1!=root2)
{
cost+=lens1[t].cost;
root[root2]=root1;
--num;
}
}
if(num>1) //极端情况 删除该点后 剩下的点通过修复边也无法构成连通图,本段if语句注释掉后,将有一个case无法通过。
{
cost=INF;
}
if(cost>0&&cost>maxcost)
{
maxcost=cost;
answerids.erase(answerids.begin(),answerids.end());
answerids.push_back(i);
}
else if(cost>0&&cost==maxcost)
answerids.push_back(i);
}
if(answerids.empty())
cout<<"0";
else
for(int i=0;i<answerids.size();++i)
{
if(i!=0)
cout<<" ";
cout<<answerids[i];
}
return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值