第四届蓝桥杯软件设计大赛已经结束,本以为进不了决赛。
很意外,竟然是java本科B组第一,特意来更新博客。
7月11日到北京参加总决赛。遗憾的是宿舍一同学没有考好,不能并肩作战了。
谢谢某人背后默默的支持,我会继续努力的!!!
<1>.世纪末的星期
2299
算法:直接调用java的API,避免出错。
import java.util.Calendar;
import java.util.Date;
public class EndDay
{
public static void main(String[] args)
{
for(int i=1999;;i+=100)
{
Calendar calendar=Calendar.getInstance();
calendar.setTime(new Date(i-1900,11,31));
if(calendar.get(Calendar.DAY_OF_WEEK)-1==0)
{
System.out.println(i);return;
}
}
}
}
<2>.马虎的算式
142
算法:排列检查一下就可以了。
public class MaHu
{
static int kinds=0;
static int a[]=new int[6];
static boolean vis[]=new boolean[10];
static void check(int a[])
{
int num1=a[1]*10+a[2];
int num2=a[3]*100+a[4]*10+a[5];
int num3=a[1]*100+a[4]*10+a[2];
int num4=a[3]*10+a[5];
if(num1*num2==num3*num4)kinds++;
}
static void dfs(int start,int n)
{
if(start==6)
{
check(a);
}
else
{
for(int i=1;i<n;i++)
{
if(vis[i]) continue;
a[start]=i;
vis[i]=true;
dfs(start+1,n);
vis[i]=false;
}
}
}
public static void main(String[] args)
{
dfs(1,10);
System.out.println(kinds);
}
}
<3>.振兴中华
35
算法:模拟向右或者向下走7步。
class Node
{
int x,y;
public Node(int xx,int yy){x=xx;y=yy;}
}
public class ZhongHua
{
static int kinds=0,dir[][]={{0,1},{1,0}};
static Node aim[]=new Node[8];
static boolean vis[][]=new boolean[4][5];
static void dfs(int start,int n)
{
if(start==n) kinds++;
else
{
Node pre=aim[start];
for(int i=0;i<2;i++)
{
int x=pre.x+dir[i][0];
int y=pre.y+dir[i][1];
if(x<4 && y<5&& !vis[x][y])
{
vis[x][y]=true;
aim[start+1]=new Node(x,y);
dfs(start+1,n);
vis[x][y]=false;
}
}
}
}
public static void main(String[] args)
{
aim[0]=new Node(0,0);
dfs(0,7);
System.out.println(kinds);
}
}
<4>.黄金连分数
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375
算法:使用BigDecilmal大数类,由于要求是100位,所以保留200位确保精度在前100位无损失,重复1000次,稳定后再截取前100位进行四舍五入。
public class FenGe
{
public static void main(String[] args)
{
BigDecimal one,ans;
ans=one=BigDecimal.ONE;
for(int i=0;i<1000;i++)
{
ans=one.add(ans);
ans=one.divide(ans, 200, BigDecimal.ROUND_HALF_UP);
System.out.println(ans);
}
System.out.println(ans.setScale(100,BigDecimal.ROUND_HALF_UP));
}
}
<5>.有理数类
new Rational(ra*x.rb+x.ra*rb, rb*x.rb)
算法:同分母。
<6>.三部排序
p++
算法:0比负数大,认真想一下就明白了。
<7>.错误票据
算法:开个100001的数组hash。同时min,max标记。难点是读取控制台输入数据。
import java.util.Scanner;
public class DuanHao
{
static int hash[]=new int [100001];
public static void main(String[] args)
{
Scanner cin=new Scanner(System.in);
int N=cin.nextInt();
int min=100001,max=-1;
int m=0,n=0;
String strLine=cin.nextLine();//过滤第一次输入n带来的回车换行
while(N--!=0)
{
strLine=cin.nextLine();
Scanner s=new Scanner(strLine);
while(s.hasNextInt())
{
int t=s.nextInt();
min=Math.min(t, min);
max=Math.max(t, max);
hash[t]++;
}
}
for(int i=min;i<=max;i++)
{
if(hash[i]==0) m=i;
if(hash[i]==2) n=i;
}
System.out.println(m+" "+n);
}
}
<8>.幸运数
算法:可以参考筛选素数。打表之后几乎不需要时间。
import java.util.Scanner;
public class XingYun2
{
static int a[]=new int[500000+1];
static void lucky(int start,int a[],int len)
{
int k=start,num=a[start];
for(int i=k;i<len;i++) if(i%num!=0) a[k++]=a[i];
if(num<len)lucky(start+1,a,k);
}
public static void main(String[] args)
{
int len=500000,kinds=0;
for(int i=1;i<len;i++) a[i]=2*i-1;
lucky(2,a,len);
Scanner cin=new Scanner(System.in);
int m=cin.nextInt();
int n=cin.nextInt();
long sta=System.currentTimeMillis();
for(int i=1;i<len;i++)
{
if(a[i]>=n || a[i]==a[i-1]) break;
if(a[i]>m && a[i]<n) kinds++;
}
System.out.println(kinds);
// System.out.println(System.currentTimeMillis()-sta);//时间
}
}
//1 1000000
//71917
//时间:1ms
<9>.带分数
算法:可参考上一篇博客。1000以内150ms内出结果,大于1000大概250ms内运行出结果。带分数
import java.util.Scanner;
public class DaiFenShu
{
static int kinds=0;
static int a[]=new int[10];
static boolean vis[]=new boolean[10];//全排列避免重复
static int sum(int start,int end)
{
int sum=0;
for(int i=start;i<end;i++) sum=sum*10+a[i+1];
return sum;
}
static void check(int a[],int n,int num)
{
int begin=1,temp=num;
while((temp=temp/10)!=0) begin++;
for(int k=1;k<begin+1;k++)
{
int num1=sum(0,k);
if(num1>=num) return;//加快跳出
for(int j=k+(n-k)/2;j<n-1;j++)
{
int num2=sum(k,j);
int num3=sum(j,n-1);
if(num2>num3 && num2%num3==0 &&num==num1+num2/num3)
{
// System.out.println(num+" = "+num1+"+"+num2+"/"+num3);
kinds++;
}
}
}
}
static void dfs(int start,int n,int num)
{
if(start==n)
{
check(a,n,num);
}
else
{
for(int i=1;i<n;i++)//全排列
{
if(vis[i]) continue;
a[start]=i;
vis[i]=true;
dfs(start+1,n,num);
vis[i]=false;
}
}
}
public static void main(String[] args)
{
Scanner cin=new Scanner(System.in);
int num=cin.nextInt();
long start=System.currentTimeMillis();
dfs(1,10,num);
long end=System.currentTimeMillis();
// System.out.println(end-start);//运行时间
System.out.println(kinds);
}
}
<10>.连号区间数
算法:如一行数据[10, 3,9 ,2 ,7,4,6,5,2, 1], 当索引j=2时,max=10,min=3根据定义:如果一个大的连续区间数包含[1,2]这个区间,那么这个区间长度肯定大于等于10-3+1=8.也就是下次的索引j直接从j+max-min-1即j=8开始,这样就省了很多次的比较max-min是否与j-i相等。特俗情况下,当该行数据是连续的自然数时,算法与双重for效率无任何差异,同样在大数据面前超时。当n=50001时大概在5500ms左右,看来算法应该写到O(n(logn))才能不会超时。如有高效算法,希望能学习下。
下面只是简单的枚举,注定悲剧。
import java.util.Scanner;
public class LianHao
{
static int kinds=0;
static void lianhao(int a[])
{
for(int i=1;i<a.length;i++)
{
int min=a[i];
int max=a[i];
for(int j=i;j<a.length;j++)
{
min=Math.min(min, a[j]);
max=Math.max(max, a[j]);
if(max-min==j-i){kinds++;}
}
}
}
public static void main(String[] args)
{
Scanner cin=new Scanner(System.in);
int n=cin.nextInt();
int a[]=new int[n+1];
for(int i=1;i<=n;i++) a[i]=cin.nextInt();
long start=System.currentTimeMillis();
lianhao(a);
System.out.println(kinds);
// System.out.println(System.currentTimeMillis()-start);时间
}
}