成绩出来了,还是可以去北京玩了,本来以为无缘的。。。加油吧决赛
第一题
标题:第几天
2000年的1月1日,是那一年的第1天。
那么,2000年的5月4日,是那一年的第几天?
注意:需要提交的是一个整数,不要填写任何多余内容。
解:125,31+29+31+30+4=125(有输入法可以打v然后输入式子直接计算,或者直接sysout计算;
第二题
标题:方格计数
如图p1.png所示,在二维平面上有无数个1x1的小方格。
我们以某个小方格的一个顶点为圆心画一个半径为1000的圆。
你能计算出这个圆里有多少个完整的小方格吗?
注意:需要提交的是一个整数,不要填写任何多余内容。
解:这道题有两种思路
思路1,只看第一象限,圆心为(0,0),然后遍历第一象限圆内的所有点( i, j ),当且仅当这个点的左上角,左边,上面的点在园内,count++;这种思路时间复杂度O(N^2),对于这道题O(10^6/4),可以在很快时间内解出来,思路简单。
思路2,只看第一象限,a点 从x轴从右往左遍历,b从a点出发,往上走,直到刚要走出圆,这时候 原点与a,a与b,形成一个矩形,count+=la*lb,然后a继续走,b继续走,又形成一个矩形,但这次lb,就要减去上次b的y坐标;
这种思路时间复杂度O(N ),因为a和b都不会往后退,最多走1000。这个思路其实很简单,我讲的不好,而且代码也很简短具体看下面代码吧;
以上 答案要乘4; 这里我贴思路2的代码,思路1就不贴了
public class Main {
public static void main(String[] args) {
int R=1000;
int a=1000,b=0,tb=b,count=0;
for(a=1000;a>=0;a--) {
while(a*a+b*b<=R*R)b++;
b--;
count+=a*(b-tb);
tb=b;
}
System.out.println(count*4); //答案 3137548
}
}
第三题
标题:复数幂
设i为虚数单位。对于任意正整数n,(2+3i)^n 的实部和虚部都是整数。
求 (2+3i)^123456 等于多少? 即(2+3i)的123456次幂,这个数字很大,要求精确表示。
答案写成 "实部±虚部i" 的形式,实部和虚部都是整数(不能用科学计数法表示),中间任何地方都不加空格,实部为正时前面不加正号。(2+3i)^2 写成: -5+12i,
(2+3i)^5 的写成: 122-597i
注意:需要提交的是一个很庞大的复数,不要填写任何多余内容。
这道题,就考你大数类,文件输出,其他没啥。
import java.io.*;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps=new PrintStream(new FileOutputStream("work.txt"));
System.setOut(ps); //文件输出
int n=123456;
BigInteger a=new BigInteger("2");
BigInteger b=new BigInteger("3");
BigInteger a1=new BigInteger("2");
BigInteger b1=new BigInteger("3");
for(int i=1;i<n;i++) {
BigInteger ta=a;
a=a.multiply(a1).subtract(b.multiply(b1));//a=a*a1-b*b1;
b=ta.multiply(b1).add(b.multiply(a1));//b=a*b1+b*a1
}
System.out.println(a+(b.compareTo(BigInteger.ZERO)>0?"+":"")+b+"i");
}
}
答案:-295705807486644677729495101551。。。 以下省略135kb
第四题
标题:测试次数
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
请填写这个最多测试次数。
注意:需要填写的是一个整数,不要填写任何多余内容。
这道题当时用二分,没意识到只有3部手机,先放着 答案是19.
第五题
快速排序 ,这道题要从头到尾读代码,才能写出正确答案。
略
第六题
给定三个整数数组 A = [A1, A2, ... AN], B = [B1, B2, ... BN], C = [C1, C2,
... CN], 请你统计有多少个三元组(i, j, k) 满足:
1 <= i, j, k <= N
Ai < Bj < Ck
【输入格式】 第一行包含一个整数N。 第二行包含N个整数A1, A2, ... AN。 第三行包含N个整数B1, B2, ... BN。
第四行包含N个整数C1, C2, ... CN。
对于30%的数据,1 <= N <= 100
对于60%的数据,1 <= N <= 1000
对于100%的数据,1 <= N <=100000 0 <= Ai, Bi, Ci <= 100000
【输出格式】 一个整数表示答案
【输入样例】
3
1 1 1
2 2 2
3 3 3
【输出样例】
27
这道题第一道编程题,emmm,说难吧也不难,说简单吧,还是需要思考一下的。
第一步
思路,先将A,B,C数组排序,先 记录每个B[i],C中有多少个数比B[i]大,思路图
设置两个指针,P1,P2;
1.先将P2往后移动到第一个大于P1指针的数,然后可以根据位置算出有几个数字大于B,记录到dB[i];
2.然后P1后移一位,P2不用回到原点,因为排好序了的,所以直接重复1。
指针不会回溯,时间复杂度O(N)。
第二步
思路 和第一步一毛一样,稍微改一下代码,比如 P2指针后移第一个大于P1的数的位置是 i,就要把i后面所有的dB[i],加到ans去,这一部用前缀和实现,依然是O(N)。
最后 输出ans。时间复杂度O(nlogn),就只有排序nlogn。给出代码 。
代码 : 这里自己写了个nextInt()读取Int;题中数据量很大10^6个整数,不敢用Scanner;
import java.io.*;
import java.util.*;
public class Main {
static DataInputStream in=new DataInputStream(System.in);
static int n;
public static void main(String[] args) throws IOException {
n=nextInt();
int[] a=new int[n],b=new int[n],c=new int[n];
f1(a);f1(b);f1(c);
//...以上输入与排序
//第一步
int p1=0,p2=0;
int[] db=new int[n],sdb=new int[n];
while(p1<n) {
while(p2<n&&c[p2]<=b[p1])p2++;
db[p1]=n-p2;
sdb[p1]=(p1==0?0:sdb[p1-1])+db[p1];//Sn=Sn-1 +an;
p1++;
}
//第二步
p1=0;p2=0;int ans=0;
while(p1<n) {
while(p2<n&&b[p2]<=a[p1])p2++;
ans+=sdb[n-1]-(p2==0?0:sdb[p2-1]);//加上b[p2]~b[n],注意处理边界
p1++;
}
System.out.println(ans);
}
static void f1(int[] a) throws IOException {
for(int i=0;i<n;i++)a[i]=nextInt();
Arrays.sort(a);
}
static int nextInt() throws IOException {
char c=(char)in.read();int x=0;
while(c<=32)c=(char)in.read();
while(c>='0'&&c<='9') {x=x*10+c-'0';c=(char)in.read();}
return x;
}
}
第九题 全球变暖
你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
【输入样例】
7
.......
.##....
.##....
....##.
..####.
...###.
.......
【输出样例】
1
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
思路:
把'.'当做0,把'#'当做-1(化作整数方便标记连通分量)
1.dfs一次,并在dfs的过程中标连通分量(每个岛给一个编号p,p从1开始)
2.在1的过程中,把会被淹没的陆地(如果周围存在海)给予特殊编号-2
3.最后统计非特殊编号个数cnt, 答案就是p-cnt;
#include <bits/stdc++.h>
using namespace std;
int n,a[1111][1111],p=0;
int hf(int i,int j){
return i>=0&&j>=0&&i<n&&j<n;
}
void dfs(int i,int j){
a[i][j]=p; //先给岛屿编号
for(int di=-1;di<=1;di++)
for(int dj=-1;dj<=1;dj++)
if(abs(di)+abs(dj)==1&&hf(i+di,j+dj)){
if(a[i+di][j+dj]==-1) dfs(i+di,j+dj);
else if(!a[i+di][j+dj]) a[i][j]=-2; // 用-2标记会被淹没的岛屿
}
}
int main() {
//..................输入处理
scanf("%d",&n);
for(int i=0;i<n;i++){
char buf[1111];
scanf("%s",&buf);
for(int j=0;j<n;j++)
if(buf[j]=='#')a[i][j]=-1;
}
//.................dfs标记连通分量
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(a[i][j]==-1){++p;dfs(i,j);}
//.................统计剩余岛屿
set<int> st;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)if(a[i][j]>0)st.insert(a[i][j]);
//................输出答案
printf("%d\n",p-st.size());
}