1、纸牌三角形
题目:A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
思路:全排列问题
代码:
public class App2 {
public static int res = 0;
public static void f(int[] arr, int n) {
if (n == arr.length) {
System.out.println(arr[0]+" "+arr[1]+" "+arr[2]+" "+arr[3]+" "+arr[4]+" "+arr[5]+" "+
arr[6]+" "+arr[7]+" "+arr[8]);
if (arr[0] + arr[1] + arr[3] + arr[5] == arr[5] + arr[6] + arr[7] + arr[8]
&& arr[5] + arr[6] + arr[7] + arr[8] == arr[0] + arr[2] + arr[4] + arr[8]) {
res += 1;
}
return;
}
for (int i = n; i < arr.length; i++) {
int temp = arr[n];//交换位置
arr[n] = arr[i];
arr[i] = temp;
f(arr, n + 1);
temp = arr[n];//将arr[]恢复
arr[n] = arr[i];
arr[i] = temp;
}
}
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
f(arr, 0);
System.out.println(res);
System.out.println(res / 6); // 答案: 144
}
}
2、取数位
题目:求1个整数的第k位数字有很多种方法。
以下的方法就是一种。
public class Main
{
static int len(int x){
if(x<10) return 1;
return len(x/10)+1;
}
// 取x的第k位数字
static int f(int x, int k){
if(len(x)-k==0) return x%10;
return ______________________; //填空
}
public static void main(String[] args)
{
int x = 23513;
//System.out.println(len(x));
System.out.println(f(x,3));
}
}
对于题目中的测试数据,应该打印5。
请仔细分析源码,并补充划线部分所缺少的代码
答案:f(x/10,k) ;
7、日期问题
题目:小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输入
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入
02/03/04
样例输出
2002-03-04
2004-02-03
2004-03-02
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
代码:
public class App7 {
public static String show(int a,int b,int c) {
String x;
String y;
if(a>59)a=2000+a;
else a=1900+a;
if(b>12) {
return "1";
}else {
if(b<10)x=0+""+b;
else x=b+"";
}
if(c>31) {
return"1";
}else if(b==4||b==6||b==9||b==11) {
if(c>30) {
return "1";
}
}else if(b==2) {
if(a%4==0) {
if(c>29) {
return "1";
}
}else {
if(c>28) {
return "1";
}
}
}
if(c>10) {
y=c+"";
}else {
y=0+""+c;
}
return a+"-"+x+"-"+y;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String str=sc.next();
String a=str.substring(0,2);
String b=str.substring(3,5);
String c=str.substring(6);
int x=Integer.parseInt(a);
int y=Integer.parseInt(b);
int z=Integer.parseInt(c);
String []str1=new String[6];
String []str2=new String[6];
str1[0]=show(x,y,z);
str1[1]=show(x,z,y);
str1[2]=show(y,x,z);
str1[3]=show(y,z,x);
str1[4]=show(z,x,y);
str1[5]=show(z,y,x);
for(int i=0;i<6;i++) {
for(int j=0;j<6;j++) {
if(str1[i].equals(str1[j])&&i!=j)str1[j]="1";
}
}
for(int i=0;i<6;i++) {
if(str1[i]!="1") {
System.out.println(str1[i]);
}
}
}
}
10、k倍区间
题目:给定一个长度为N的数列,A1, A2, … AN,如果其中一段连续的子序列Ai, Ai+1, … Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出
输出一个整数,代表K倍区间的数目。
例如,
输入:
5 2
1
2
3
4
5
程序应该输出:
6
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
思路:前缀和,数学
代码:
import java.util.Scanner;
public class App10 {
static int a[]=new int [100001];
static int b[]=new int [100001];
static int c[]=new int [100001];
static Scanner sc=new Scanner(System.in);
public static void main(String[] args) {
int n=sc.nextInt();
int k=sc.nextInt();
a[0]=sc.nextInt();
b[0]=a[0];
for(int i=1;i<n;i++) {//计算前缀和
a[i]=sc.nextInt();
b[i]=b[i-1]+a[i];
b[i]%=k;
}
for(int i=0;i<n;i++) {
b[i]%=k;
c[b[i]]++;
}
int ans=0;
for(int i=0;i<k;i++) {//任意两个相同的数相减得到的取钱可以时K被区间
ans+=c[i]*(c[i]-1)/2;
}
System.out.println(ans+c[0]);
}
}