基础练习 矩形面积交
问题描述
平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。
输入格式
输入仅包含两行,每行描述一个矩形。
在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。
输出格式
输出仅包含一个实数,为交的面积,保留到小数后两位。
思路:翻译一下就是求出相交矩形的长和宽,再翻译一下就是利用输入的值做差求出相交矩形的顶点坐标
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
double[] x=new double[4];
double[] y=new double[4];
for(int i=0;i<4;i++)
{
x[i]=sc.nextDouble();
y[i]=sc.nextDouble();
}
double x1=Math.abs((x[0]+x[1])-(x[2]+x[3]));
double x2=Math.abs(x[0]-x[1])+Math.abs(x[2]-x[3]);
double y1=Math.abs((y[0]+y[1])-(y[2]+y[3]));
double y2=Math.abs(y[0]-y[1])+Math.abs(y[2]-y[3]);
double s=0;
if(x1<x2&&y1<y2)
{
Arrays.sort(x);
Arrays.sort(y);
s=Math.abs(x[1]-x[2])*Math.abs(y[1]-y[2]);
}
System.out.printf("%.2f",s);
}
}
基础练习 完美的代价
问题描述
回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
交换的定义是:交换两个相邻的字符
例如mamad
第一次交换 ad : mamda
第二次交换 md : madma
第三次交换 ma : madam (回文!完美!)
输入格式
第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
第二行是一个字符串,长度为N.只包含小写字母
输出格式
如果可能,输出最少的交换次数。
否则输出Impossible
思路:首先判断能否转换
1.impossible的情况:如果有一个字符出现的次数是奇数次数,而且n是偶数,那么不可能构成回文
如果n是奇数,但是已经有一个字符出现的次数是奇数次数了,那么如果又有一个字符是奇数次数,就不可能构成回文。
2.如果n是奇数,计算中间那个字符交换的次数的时候,不需要模拟把这个数移动到中间去,因为移动到中间的话假设有一对数都在左边或者都在右边,那么交换成回文的时候就要经过中间,就会每次把cnt多加了1,而这个1是没有必要的,因为可以所有的回文移动完了之后再把这个独立的奇数移动过去,才能保证交换次数最少。
对于字符串第一个字符,从字符串的最后一个字符开始匹配,如果找到第一个匹配的位置,将它换到倒数第二的位置,并记录这一次转换所需的次数;如果没有找到匹配的位置,这个字符可能就会是最中间的那个字符,用一个布尔变量记录是否需要将这个可能是中间的字符是否存在。题目的关键就是这个可能是中间的字符需不需要换到中间位置的这种情况,如果将这个字符换到中间,那么以后的字符每次变换都会改变这个中间字符的位置。这个中间字符的左边是已经变换好的,只需要将中间字符的右边作变换就可以了,所以可以将中间字符在最后做变换(下面的代码没有在最后实际作变换,只是统计了它变换需要的次数),最后将右边的字符作回文处理就可以了,如果处理的过程中再次出现可能是中间的字符,那么这种情况就是不可能的了。
附详细链接:http://blog.csdn.net/u011506951/article/details/26382569
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(reader.readLine());
char[] s = reader.readLine().toCharArray();
reader.close();
if (palindrome(s, 0, len - 1)) {
System.out.println(cnt);
} else {
System.out.println("Impossible");
}
}
private static int cnt = 0;
private static boolean haveMiddle = false;
private static boolean palindrome(char[] s, int a, int b) {
if (b <= a) {
return true;
}
// 从最后的位置开始遍历字符串
for (int i = b; i > a; i--) {
if (s[a] == s[i]) {
exchangeTo(s, i, b);
cnt += getExchangeTimes(i, b);
return palindrome(s, a + 1, b - 1);
}
}
// 如果没有出现过中间字符
if (!haveMiddle) {
haveMiddle = true;
cnt += getExchangeTimes(a, s.length / 2);
return palindrome(s, a + 1, b);
}
return false;
}
private static int getExchangeTimes(int a, int b) {
return b - a;
}
private static void exchangeTo(char[] s, int a, int b) {
char temp = s[a];
for (int i = a; i < b; i++) {
s[i] = s[i + 1];
}
s[b] = temp;
}
}
基础练习 数的读法
问题描述
Tom教授正在给研究生讲授一门关于基因的课程,有一件事情让他颇为头疼:一条染色体上有成千上万个碱基对,它们从0开始编号,到几百万,几千万,甚至上亿。
比如说,在对学生讲解第1234567009号位置上的碱基时,光看着数字是很难准确的念出来的。
所以,他迫切地需要一个系统,然后当他输入12 3456 7009时,会给出相应的念法:
十二亿三千四百五十六万七千零九
用汉语拼音表示为
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
这样他只需要照着念就可以了。
你的任务是帮他设计这样一个系统:给定一个阿拉伯数字串,你帮他按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符格开。
注意必须严格按照规范,比如说“10010”读作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”读作“shi wan”而不是“yi shi wan”,“2000”读作“er qian”而不是“liang qian”。
输入格式
有一个数字串,数值大小不超过2,000,000,000。
输出格式
是一个由小写英文字母,逗号和空格组成的字符串,表示该数的英文读法。
思路:根据数字个数确定单位
import java.util.Scanner;
public class Main {
private static void change(int n){
int i,j;
String[] c={"ling ","yi ","er ","san ","si ","wu ","liu ","qi ","ba ","jiu "};
String[] d={"","shi ","bai ","qian ","wan ","shi ","bai ","qian ","yi ","shi ","bai "};
String ss=n+"";
String buffer=new String();
boolean b=true;
//第一次出现零
for ( i=0;i<ss.length();i++)
{
for( j=0;j<=9;j++)
if(ss.charAt(i)==j+'0')
break;
if((ss.length()+2)%4==0&&i==0&&j==1)
buffer+=d[ss.length()-i-1];
else if(i!=ss.length()-1&&j==0)
{
if(b)
{
buffer+=c[j];
b=false;
}
}
else if(i==ss.length()-1&&j==0)
{
if(!b)
buffer=buffer.substring(0,buffer.length()-5) ;//如果最后一个也为0,则去掉之前添加的 ling
}
else
{
buffer+=c[j]+d[ss.length()-i-1];
b=true;
}
}
System.out.println(buffer);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
change(n);
}
}
基础练习 Sine之舞
问题描述
最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功。所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力。
不妨设
An=sin(1–sin(2+sin(3–sin(4+...sin(n))...)
Sn=(...(A1+n)A2+n-1)A3+...+2)An+1
FJ想让奶牛们计算Sn的值,请你帮助FJ打印出Sn的完整表达式,以方便奶牛们做题。
输入格式
仅有一个数:N<201。
输出格式
请输出相应的表达式Sn,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。
思路:递归
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
String s=S(n,1,1);
System.out.println(s);
}
public static String S(int n,int i,int j)
{
if(i==n) return A(n,i,j)+"+"+i;
return "("+S(n,i+i,j)+")"+A(n,i,j)+i;
}
public static String A(int n,int i,int j)
{
if(i==n) return "sin("+j+")";
if(i%2==0) return "sin("+i+"-"+A(n,i+1,j+1)+")";
else return "sin("+i+"+"+A(n,i+1,j+1)+")";
}
}