算法题
回文判定
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String s=sc.nextLine();
StringBuffer sb=new StringBuffer();
sb.append(s);//StringBuffer的拼接相当于放到连续的数组
sb.reverse();//StringBuffer的字符反转方法
String ss=sb.toString();//反转的字符转成字符串与原字符对比
if(s.equals(ss)){
System.out.print("Y");
}else{
System.out.print("N");
}
}
}
二分:分巧克力
开始d的范围是1~最大边长D,就试试中间值D/2,如果这个值大了,就把范围缩小为 0D/2,如过这个值小了,就把范围缩小到D/2/D;第二次,取D/4试试…直到合适的为止
- java
import java.util.Scanner;
public class Main{
private static int N=100001;
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int k=sc.nextInt();
int []h=new int[N];
int []w=new int[N];
for(int i=1;i<=n;i++){
h[i]=sc.nextInt();
w[i]=sc.nextInt();
}
int d=0;//边长
int L=1;
int R=N;
while(L<=R){
int mid=(L+R)>>1;
int cnt=0;
for(int i=1;i<=n;i++){
cnt+=(h[i]/mid)*(w[i]/mid);//n块,每块的个数和
}
if(cnt>=k){
//够分
L=mid+1;//新的搜索区间是右半部分,R不变,更新L=mid+1
d=mid;
}else{
//不够分
R=mid-1; //(L=R时跳出循环)新的搜索区间是左半部分,所以L不变,调整R=mid–1。
}
}
System.out.print(d); //输出符合的边长
}
}
- C++
#include<bits/stdc++.h>
using namespace std;
int n,k;
int h[100010],w[100010];
bool check(int d){
int num=0;
for(int i=0;i<n;i++)
num += (h[i]/d)*(w[i]/d);
if(num>=k) return true; //够分
else return false; //不够分
}
int main(){
cin >>n>>k;
for(int i=0;i<n;i++) cin>>h[i]>>w[i];
int L=1, R=100010;
//整数二分法的L、R、mid如果处理不当,极容易死循环。
//请仔细领会下面两种写法
// 第一种写法:
while(L<R) {
int mid=(L+R+1)>>1; //除2,向右取整
if(check(mid))
L=mid; //新的搜索区间是右半部分,所以R不变,调整L=mid;
else
R=mid-1; //新的搜索区间是左半部分,所以L不变,调整R=mid–1。
}
cout << L;
// 第二种写法:
/* while(L<R) {
int mid=(L+R)>>1; //除2,向左取整
if(check(mid))
L=mid+1;//新的搜索区间是右半部分,R不变,更新L=mid+1。
else
R=mid; //新的搜索区间是左半部分,L不变,更新R=mid
}
cout << L-1;
*/
return 0;
}
二分:跳石头
import java.util.Scanner;
public class Main{
static int n=0,m=0,len=0;
static int []st=new int[50005];
//判断二分的d能否满足条件m
public static boolean