目录
用 [TOC]
来生成目录:
-
-
- 目录
- 链表插入删除查找
- 队列入队出队是否空 已测试
- 栈入栈出栈是否空
- 堆插入删除大顶堆小顶堆 验证OK
- 哈希putgetremove 已验证
- 字典树 已验证 POJ1204
- KMP算法
- 最长上升子串已验证H58
- 哈夫曼树
- 快速排序
- 计数排序验证OK
- 归并排序
- 二叉树前序中序后序
- 一般树前序
- 一般树中序
- 一般树后序
- 二叉搜索树插入删除查找最大值最小值前驱后继 测试ok
- 删除o1的树插入的子节是链表
- 二分查找
- first same num index OKsamsung0826
- last same num index OKsamsung0826
- 位运算
- 大数-
- 第K小数
- 最近点对
- 顺时针旋转
- 方块消消乐俄罗斯方块 -ok
- 查表
- 求一个数的所有因子预处理打表 OK
- 最大公约数 OK
- 闰年判定
- 青蛙
- 判断两条线段是否相交
-
链表:插入,删除,查找
队列:入队,出队,是否空 –已测试
class Queue{
Node dil;
public Queue(Node dil) {
this.dil = dil;
}
void enQ(Node curr){
curr.next = dil;
curr.pre = dil.pre;
dil.pre.next = curr;
dil.pre = curr;
}
Node deQ(){
Node curr = dil.next;
delete(curr);
return curr;
}
void delete(Node curr){
curr.pre.next = curr.next;
curr.next.pre = curr.pre;
curr.pre = dil;
curr.next = dil;
}
boolean isEmpty(){
return dil.next==dil?true:false;
}
}
–未测试
class Queue{
Data qil;
public Queue() {
qil = new Data(null);
qil.next = qil;
qil.pre = qil;
}
void enQueue(Object o){
Data curr = new Data(o);
curr.next = qil;
curr.pre = qil.pre;
qil.pre.next = curr;
qil.pre = curr;
}
Object deQueue(){
Data curr = qil.next;;
curr.pre.next = curr.next;
curr.next.pre = curr.pre;
curr.pre = qil;
curr.next = qil;
return curr.o;
}
boolean isEmety(){
return qil.pre==qil?true:false;
}
class Data{
Object o;
Data next=qil,pre=qil;
public Data(Object m) {
o = m;
}
}
}
栈:入栈,出栈,是否空
class Stack{
Data sil;
public Stack() {
sil = new Data(null);
sil.next = sil;
sil.pre = sil;
}
void push(Object o){
Data curr = new Data(o);
curr.next = sil;
curr.pre = sil.pre;
sil.pre.next = curr;
sil.pre = curr;
}
Object pop(){
Data curr = sil.pre;;
curr.pre.next = curr.next;
curr.next.pre = curr.pre;
curr.pre = sil;
curr.next = sil;
return curr.o;
}
boolean isEmety(){
return sil.pre==sil?true:false;
}
class Data{
Object o;
Data next=sil,pre=sil;
public Data(Object m) {
o = m;
}
}
}
static class StackInt{
int top=-1;
int data[];
public StackInt(int size) {
data = new int[size];
}
void push(int a){
data[++top] = a;
}
int pop(){
if(top==-1){
System.out.println("error");
return -1;
}
int v = data[top];
top--;
return v;
}
boolean isEmpty(){
return top==-1?true:false;
}
}
堆:插入,删除,大顶堆,小顶堆 ——验证OK
public class Heap {
public Heap(int size) { //size: 堆的大小
data = new int[size+1];
}
/**
* 为了方便计算,从下标1开始存入数据
* 下标n的节点的父节点为n/2,左孩子n*2。右孩子n*2+1
*/
int data[];
int size = 1; //data的数据长度
void add(int newData){
data[size] = newData;
up(size); //小顶堆
size++;
}
//
private void up(int nodeIndex) {
while(nodeIndex>1){
int p = nodeIndex/2;
if(data[p]>data[nodeIndex]) {//当前是小顶堆,大顶堆,方向相反
swap(p,nodeIndex);
nodeIndex = p;
}
if(p!=nodeIndex) return;
}
}
int delete(){
int tmp = data[1];
data[1] = data[--size];
down(1);
return tmp;
}
private void down(int i) {
int l = i*2;
int r = l+1;
int min;
while(l<size){
min = i;
if(data[l]<data[min]) min = l; //当前是小顶堆,大顶堆,方向相反
if(r<size&&data[r]<data[min]) min = r; //当前是小顶堆,大顶堆,方向相反
if( min == i) return;
swap(i,min);
i = min;
l = i*2;
r = l+1;
}
}
private void swap(int a, int b) {
int tmp = data[a];
data[a] = data[b];
data[b] = tmp;
}
}
哈希:put,get,remove –已验证
static class Hash{
int size;
Node pool[];
public Hash(int size) {
this.size = size;
pool = new Node[size];
}
int getKey(int id){
return id%size;
}
void put(Object o,int id){
int key = getKey(id);
if(pool[key]==null) {
pool[key]=new Node();
pool[key].pre = pool[key];
pool[key].next = pool[key];
pool[key].id = -1;
}
Node node = new Node();
node.o = o;
node.id = id;
insert(node,pool[key]);
}
void insert(Node node,Node header){
node.next = header;
node.pre = header.pre;
header.pre.next = node;
header.pre = node;
}
Object get(int id){
int key = getKey(id);
Node curr = pool[key].next;
while(curr!=pool[key]&&curr.id!=id){
curr = curr.next;
}
if(curr==pool[key]) return null;
return curr.o;
}
void print(){
for (int i = 0; i < size; i++) {
if(pool[i]==null){
System.out.println(i+": is empty");
}else{
Node curr = pool[i].next;
System.out.print(i+":");
while(curr!=pool[i]){
System.out.print((int)curr.o+" ");
curr = curr.next;
}
System.out.println();
}
}
}
class Node{
Node pre,next;
int id;
Object o;
}
}
class Hash{
Data dil;
Data map[];
int size;
public Hash(int size) {
dil = new Data(null,-2);
dil.next = dil;
dil.pre = dil;
this.size = size;
map = new Data[size];
}
void put(Object o,int id){
int key = getKey(id);
if(map[key]==null) map[key] = new Data(null,-1);
Data d = new Data(o,id);
d.next = map[key].next;
d.pre = map[key];
map[key].next.pre = d;
map[key].next = d;
}
Object get(int id){
int key = getKey(id);
Data curr = map[key];
if(curr==null) return null;
while(curr.next!=dil&&curr.id!=id) curr = curr.next;
return curr.o;
}
void remove(int id){
int key = getKey(id);
Data curr = map[key];
while(curr.next!=dil&&curr.id!=id) curr = curr.next;
curr.next.pre = curr.pre;
curr.pre.next = curr.next;
curr.pre = dil;
curr.next = dil;
}
int getKey(int id){
return id%size;
}
class Data{
Object o;
int id;
Data next=dil,pre=dil;
public Data(Object m,int i) {
o = m;
id = i;
}
}
}
字典树 –已验证 POJ1204
// maketree 根据work数组建立字典树,leafFlag为叶子节点标记,默认是-1
// work可以改写成其他的数组形式用于建立树
// 后插入树内的work会插到父节点的第一个子节点上
static Node root;
static int leafFlag = 1;
static void init(){
root = new Node('1');
root.ch = root;
root.bro = root;
makeTree("HELLO_HUA", root, leafFlag);
makeTree("HELLO_YY", root, leafFlag);
makeTree("HEO_YY", root, leafFlag);
System.out.println(searchArray("HEO_YY".toCharArray()));
}
static void makeTree(String word,Node root,int leafFlag){ //word为要插入的所有的元素的集合
char cs[] = word.toCharArray();
Node parent = root;
Node tmp = null;
for (int i = 0; i < cs.length; i++) {
tmp = insert(parent,cs[i]);
parent = tmp;
}
tmp.leafFlag = leafFlag; //叶子节点需要单独标记
}
static void search(int x,int y,int x_inc,int y_inc,char map[][],int result[][],int dis){
int _x = x , _y = y;
Node parent = root;
Node tmp;
while(x>=0&&x<l&&y>=0&&y<c&&(tmp=checkNode(parent, map[x][y]))!=root){
if(tmp.leafFlag>-1){ //有意义的节点
result[tmp.leafFlag][0] = _x;
result[tmp.leafFlag][1] = _y;
result[tmp.leafFlag][2] = dis;
}
// 更新 parent和key ,都指向下一个需要判断的值
parent = tmp;
x+=x_inc;
y+=y_inc;
}
}
//搜索指定数组,有返回true,没有false
static boolean searchArray(char word[]){
Node parent = root;
Node tmp;
int i = 0;
char key = word[i];
while(i<word.length&&(tmp=checkNode(parent, key))!=root){
if(tmp.leafFlag==leafFlag){ //有意义的节点
return true;
}
// 更新 parent 指向下一个需要判断的值
parent = tmp;
// 更新key 指向下一个需要判断的值
if(++i<word.length) key = word[i];
else break;
}
return false;
}
//在parent的所有child中查找是否有key值的点,并返回
static Node checkNode(Node parent,char key){
Node curr = parent.ch;
while(curr!=root&&curr.id!=key) curr = curr.bro;
return curr;
}
//在parent的子节点中插入 值为key的节点,返回当前key值的节点
static Node insert(Node parent , char key){
Node tmp= checkNode(parent,key);
if(tmp==root){
tmp = new Node(key);
tmp.bro = parent.ch;
parent.ch = tmp;
}
return tmp;
}
static class Node {
char id;
int leafFlag = -1; // 默认标记 -1
Node ch = root;
Node bro = root;
public Node(char ids) {
id = ids;
}
}
KMP算法
//查找str中是否有dest,有返回下标(从0开始),无匹配返回-1
public static int kmpString(String str, String dest){//str文本串:待匹配, dest 模式串
//求next数组,可分离。next数组是根据dest求出的,对于一个dest只要求一次next数组就可以了
int[] next = new int[dest.length()];
next[0] = 0;
for(int i = 1,j = 0; i < dest.length(); i++){
while(j > 0 && dest.charAt(j) != dest.charAt(i)){
j = next[j - 1];
}
if(dest.charAt(i) == dest.charAt(j)){
j++;
}
next[i] = j;
}
//
for(int i = 0, j = 0; i < str.length(); i++){
while(j > 0 && str.charAt(i) != dest.charAt(j)){
j = next[j - 1];
}
if(str.charAt(i) == dest.charAt(j)){
j++;
}
if(j == dest.length()){
return i-j+1;
}
}
return -1;
}
public static int kmpCharArray(char str[], char dest[]){//str文本串:待匹配, dest 模式串
//求next数组,可分离。next数组是根据dest求出的,对于一个dest只要求一次next数组就可以了
int[] next = new int[dest.length];
next[0] = 0;
for(int i = 1,j = 0; i < dest.length; i++){
while(j > 0 && dest[j] != dest[i]){
j = next[j - 1];
}
if(dest[i] == dest[j]){
j++;
}
next[i] = j;
}
//
for(int i = 0, j = 0; i < str.length; i++){
while(j > 0 && str[i] != dest[j]){
j = next[j - 1];
}
if(str[i] == dest[j]){
j++;
}
if(j == dest.length){
return i-j+1;
}
}
return -1;
}
最长上升子串–已验证H58
//最长上升子序列nlogn模板
//入口参数:数组名+数组长度
//数组下标从0号开始。
/**//BEGIN_TEMPLATE_BY_ABILITYTAO_ACM
static int bsearch(int c[],int n,int a)
{
int l=0, r=n-1;
while(l<=r)
{
int mid = (l+r)/2;
if( a > c[mid] && a <= c[mid+1] ) return mid+1; // >&&<= 换为: >= && <
else if( a < c[mid] ) r = mid-1;
else l = mid+1;
}
return -1;
}
static int LIS(int a[], int n)
{
int i, j, size = 1;
int c[]=new int[n+1];
int dp[]=new int[n+1];
c[1] = a[0]; dp[1] = 1;
for(i=1;i<n;++i)
{
if( a[i] <= c[1] ) j = 1;// <= 换为: <
else if( a[i] >c[size] )
j=++size; // > 换为: >=
else
j = bsearch(c, size, a[i]);
c[j] = a[i]; dp[i] = j;
}
return size;
}
哈夫曼树
快速排序
void quickSort(int low,int high,int a[]){
if(high>low){
int l = low, h = high , x = a[l];
while(h>l){
while(h>l&&a[h]>=x) h--;
if(h>l) a[l++] = a[h];
while(h>l&&a[l]<=x) l++;
if(h>l) a[h--] = a[l];
}
a[l] = x;
quickSort(low,h-1,a);
quickSort(l+1,high,a);
}
}
// 非递归
static int partition(int vec[],int low,int high){
int pivot=vec[low]; //任选元素作为轴,这里选首元素
while(low<high){
while(low<high && vec[high]>=pivot)
high--;
vec[low]=vec[high];
while(low<high && vec[low]<=pivot)
low++;
vec[high]=vec[low];
}
//此时low==high
vec[low]=pivot;
return low;
}
static void quicksort2(int low,int high,int vec[]){
StackInt st = new StackInt(high+1);
if(low<high){
int mid=partition(vec,low,high);
if(low<mid-1){
st.push(low);
st.push(mid-1);
}
if(mid+1<high){
st.push(mid+1);
st.push(high);
}
//其实就是用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作
while(!st.isEmpty()){
int q=(int) st.pop();
int p=(int) st.pop();
mid=partition(vec,p,q);
if(p<mid-1){
st.push(p);
st.push(mid-1);
}
if(mid+1<q){
st.push(mid+1);
st.push(q);
}
}
}
}
static class StackInt{
int top=-1;
int data[];
public StackInt(int size) {
data = new int[size];
}
void push(int a){
data[++top] = a;
}
int pop(){
if(top==-1){
System.out.println("error");
return -1;
}
int v = data[top];
top--;
return v;
}
boolean isEmpty(){
return top==-1?true:false;
}
}
计数排序–验证OK
static int[] countSort(int a[],int size){ //size是值域的范围
int count[] = new int[size+1];
int result[] = new int[a.length];
for (int i = 0; i < a.length; i++) { //频率统计
count[a[i]]++;
}
// for (int i = 1; i < count.length; i++) {//升序: 累加,计算排序后位置,决定升序及降序
// count[i] = count[i] + count[i-1];
// }
for (int i = count.length-2; i >= 0; i--) {//降序:累加,计算排序后位置,决定升序及降序
count[i] = count[i] + count[i+1];
}
for (int i = result.length-1; i >= 0; i--) { //输出排序后队列,为了保证稳定性,i需要降序
result[--count[a[i]]] = a[i];
}
return result;
}
归并排序
long result = 0; //逆序对个数
void mergeSort(int data[],int low , int high){ //参数是数组下标
if(high>low){
int mid = low+((high-low)>>1);
mergeSort(data,low,mid);
mergeSort(data,mid+1,high);
merge(data,low,mid,high);
}
}
//合并连个有序序列
void merge(int data[],int low,int mid,int high){
int temp[] = new int[high-low+1];
int i=low ,j=mid+1,k=0;
while(i<=mid&&j<=high){
if(data[i]>data[j]){
result= result+(j-(low+k));
temp[k++] = data[j++];
}else{
temp[k++] = data[i++];
}
}
while(i<=mid){
temp[k++] = data[i++];
}
while(j<=high){
temp[k++] = data[j++];
}
for (i = 0; i < k; i++) {
data[low+i] = temp[i];
}
}
二叉树:前序,中序,后序
void preOrder(Node root){
if(root==nil) return;
// to do
preOrder(root.l);
preOrder(root.r);
}
void midOrder(Node root){
if(root==nil) return;
preOrder(root.l);
// to do
preOrder(root.r);
}
void postOrder(Node root){
if(root==nil) return;
preOrder(root.l);
preOrder(root.r);
// to do
}
void preOrder(Node root){
Stack s = new Stack();
Node curr = root;
while(!s.isEmpty()||curr!=nil){
while(curr!=nil){
System.out.println(curr.id);
s.push();
curr = curr.l;
}
curr = s.pop();
curr = curr.l;
}
}
void midOrder(Node root){
Stack s = new Stack();
Node curr = root;
while(!s.isEmpty()||curr!=nil){
while(curr!=nil){
s.push();
curr = curr.l;
}
curr = s.pop();
System.out.println(curr.id);
curr = curr.l;
}
}
void postOrder(Node root){
Stack s1 = new Stack();
Stack s2 = new Stack();
Node curr = root;
s1.push(curr);
while(!s1.isEmpty()){
curr = s1.pop();
s2.push(curr);
if(curr.l!=nil) s1.push(curr.l);
if(curr.r!=nil) s1.push(curr.r);
}
while(!s2.isEmpty()){
curr = s2.pop():
System.out.println(curr.id);
}
}
一般树:前序
void postOrder(Node root){
int size = 0;
Stack s = new Stack();
Node curr = root;
while(!s.isEmety()||curr!=nil){
while(curr!=nil){
System.out.println(curr.id);
size+=curr.getSize();
s.push(curr);
curr = curr.ch;
}
curr = (Node) s.pop();
if(curr==root) curr = nil;
else curr = curr.bro;
}
}
一般树:中序
void postOrder(Node root){
int size = 0;
Stack s = new Stack();
Node curr = root;
while(!s.isEmety()||curr!=nil){
while(curr!=nil){
size+=curr.getSize();
s.push(curr);
curr = curr.ch;
}
curr = (Node) s.pop();
System.out.println(curr.id);
if(curr==root) curr = nil;
else curr = curr.bro;
}
}
一般树:后序
void postOrder(Node root){
Stack s1 = new Stack();
Stack s2 = new Stack();
Node curr = root;
s1.push(curr);
while(!s1.isEmpty()){
curr = s1.pop():
s2.push(curr):
if(curr.ch!=nil){
curr = curr.ch;
while(curr!=nil) {
s1.push(curr);
curr = curr.bro;
}
}
}
while(!s2.isEmpty()){
curr = s2.pop();
System.put.println(curr.id);
}
}
二叉搜索树:插入,删除,查找,最大值,最小值,前驱,后继 –测试ok
class Tree{
Node nil;
public Tree(Node nil) {
this.nil = nil;
}
void insert(Node node){
Node curr = nil.r;
Node parent = nil;
while(curr!=nil){
parent = curr;
if(node.id<curr.id) curr = curr.l;
else if(node.id>curr.id) curr = curr.r;
}
if(node.id<parent.id) parent.l = node;
else parent.r = node;
node.p = parent;
}
void delete(Node node){
if(node.r==nil&&node.l==nil){
if(node.p.l==node) node.p.l = nil;
else if(node.p.r==node) node.p.r = nil;
node.p = nil;
}else if(node.l!=nil&&node.r==nil){
cover(node.l,node);
}else if(node.r!=nil&&node.l==nil){
cover(node.r,node);
}else{
Node post = getPost(node);
delete(post);
//
if(node.p.l==node) node.p.l = post;
else if(node.p.r==node) node.p.r = post;
node.l.p = post;
node.r.p = post;
//
post.p = node.p;
post.l = node.l;
post.r = node.r;
//
node.p = nil;
node.l = nil;
node.r = nil;
}
}
void cover(Node child,Node parent){ //n1替换n2
child.p = parent.p;
if(parent.p.l==parent) parent.p.l=child;
else if(parent.p.r==parent) parent.p.r = child;
parent.p = nil;
if(parent.l==child) parent.l= nil;
else if(parent.r==child) parent.r = nil;
}
Node getPre(Node node){
Node curr = node;;
if(node.l!=nil){
curr = node.l;
while(curr.r!=nil) curr = curr.r;
}else{
curr = node.p;
while(curr!=nil&&curr.id>node.id) curr = curr.p;
}
return curr;
}
Node getPost(Node node){
Node curr = nil;;
if(node.r!=nil){
curr = node.r;
while(curr.l!=nil) curr = curr.l;
}else{
curr = node.p;
while(curr!=nil&&curr.id<node.id) curr = curr.p;
}
return curr;
}
Node getMax(){
Node curr = nil.r;
while(curr.r!=nil) curr = curr.r;
return curr;
}
}
删除o1的树,插入的子节是链表
Node nil;
class Node{
Node ch,preBro,nextBro,p=nil;
int id;
public Node(int id) {
this.id = id;
}
public Node() {
}
void init(){
ch = new Node();
ch.preBro = ch;
ch.nextBro = ch;
}
}
void insert(Node child,Node parent){
//如果插入队尾
child.nextBro = parent.ch;
child.preBro = parent.ch.preBro;
parent.ch.preBro.nextBro = child;
parent.ch.preBro = child;
// //如果插入队头
// child.preBro = parent.ch;
// child.nextBro = parent.ch.nextBro;
// parent.ch.nextBro.preBro = child;
// parent.ch.nextBro = child;
}
void preOrder(Node root){
System.out.println(root.id);
Node curr = root.ch.nextBro;
while(curr!=root.ch) {
preOrder(curr);
curr = curr.nextBro;
}
}
void postOrder(Node root){
Node curr = root.ch.nextBro;
while(curr!=root.ch) {
postOrder(curr);
curr = curr.nextBro;
}
System.out.println(root.id);
}
void delete(Node node){
Node p = node.p;
node.preBro.nextBro = node.nextBro;
node.nextBro.preBro = node.preBro;
node.preBro = nil;
node.nextBro = nil;
node.p = nil;
}
void cover(Node newOne,Node oldOne){ //new继承old的父子关系
newOne.p = oldOne.p;
newOne.nextBro = oldOne.nextBro;
newOne.preBro = oldOne.preBro;
oldOne.ch.nextBro.preBro = newOne.ch;
oldOne.ch.preBro.nextBro = newOne.ch;
newOne.ch.nextBro = oldOne.ch.nextBro;
newOne.ch.preBro = oldOne.ch.preBro;
oldOne.ch.nextBro = nil;
oldOne.ch.preBro = nil;
}
二分查找
1.非递归代码
public static int biSearch(int []array,int a){
int lo=0;
int hi=array.length-1;
int mid;
while(lo<=hi){
mid=(lo+hi)/2;
if(array[mid]==a){
return mid+1;
}else if(array[mid]<a){
lo=mid+1;
}else{
hi=mid-1;
}
}
return -1;
}
2.递归实现
public static int sort(int []array,int a,int lo,int hi){
if(lo<=hi){
int mid=(lo+hi)/2;
if(a==array[mid]){
return mid+1;
}
else if(a>array[mid]){
return sort(array,a,mid+1,hi);
}else{
return sort(array,a,lo,mid-1);
}
}
return -1;
}
first same num index ——OK,samsung0826
public static int biSearch(int []array,int a){ //返回的是下标
int n=array.length;
int low=0;
int hi=n-1;
int mid=0;
while(low<hi){
mid=(low+hi)/2;
if(array[mid]<a){
low=mid+1;
}else{
hi=mid;
}
}
if(array[low]!=a){
if(a>array[low][0]){ //a 在 low的右边
return new int[]{1,low};
}else{ //a 在 low的左边
return new int[]{-1,low};
}
return -1;
}else{
return low;
}
}
last same num index ——OK,samsung0826
public static int biSearch(int []array,int a){//返回的是下标
int n=array.length;
int low=0;
int hi=n-1;
int mid=0;
while(low<hi){
mid=(low+hi+1)/2;
if(array[mid]<=a){
low=mid;
}else{
hi=mid-1;
}
}
if(array[low]!=a){
return -1;
}else{
return hi;
}
}
位运算:
1^1=0
0^0=0
0^1=1
1^0=1
while((x>>1!=0)){
x&0x00000001
x=(x>>1)
}
大数+,-, * , /
package samsungpro.samsung0923;
//没有负数运算,且商大于或者小于int需要使用2个不同的API
public class BigNum {
int size;
int maxValue = 10000;
public BigNum(int bitSize) {
this.size = bitSize;
size++;
}
class Num{
Bit set[];
public Num() {
set = new Bit[size];
for (int i = 0; i < size; i++) {
set[i] = new Bit();
}
}
int getValue(int index){
return set[index].value;
}
void setValue(int index,int value){
set[index].value = value;
}
void setInc(int index,int value){
set[index].inc = value;
}
int getInc(int index){
return set[index].inc;
}
}
class Bit{
int value;
int inc;
}
//opration
Num jia(Num n1,Num n2){
Num result = new Num();
for (int i = 0; i < size; i++) {
int sum = n1.getValue(i)+n2.getValue(i)+result.getInc(i);
if(i+1<size) result.setInc(i+1, sum/maxValue);
result.setValue(i, sum%maxValue);
result.setInc(i, 0);
}
return result;
}
Num jian(Num n1,Num n2){
Num result = new Num();
for (int i = 0; i < size; i++) {
int sum = n1.getValue(i)-n2.getValue(i)+n1.getInc(i);
if(sum<0&&i+1<size){
n1.setInc(i+1, -1);
sum+=maxValue;
}
result.setValue(i, sum);
n1.setInc(i, 0);
}
return result;
}
Num cheng(Num n1,Num n2){
Num result = new Num();
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if(i+j<size){
int sum = n1.getValue(i)*n2.getValue(j)+result.getInc(i+j)+result.getValue(i+j);
if(i+j+1<size) {
int temp = sum/maxValue;
result.setInc(i+j+1, temp);
}
int temp = sum%maxValue;
result.setValue(i+j, temp);
result.setInc(i+j, 0);
}
}
}
return result;
}
Num chu(Num n1,Num n2){ //商不超出int
Num result = new Num();
if(compare(n1,n2)<1) return result;
int low = 1 ,high = 2000000000;
while(true){
int mid = low+((high-low)>>1);
Num mid32 = intToNum32(mid);
Num temp = cheng(n2,mid32);
int m0 = compare(n1,temp);
int m2 = compare(n1,jia(n2,temp));
if(m0==0||(m0==1&&m2==-1)){// n1=n2*mid || n2*mid < n1 < n2+n2*mid
return intToNum32(mid);
}else if(m0==-1){ //n1<n2*mid
high = mid;
}else if(m2==0){ // n1 = n2+n2*mid
return intToNum32(mid+1);
}else if(m2==1){ //n1 > n2+n2*mid
low = mid+1;
}
}
}
int compare(Num n1,Num n2){ //1: n1>n2 0:n1=n2 -1:n1<n2
for (int i = size-1; i>=0; i--) {
int s1 = n1.getValue(i);
int s2 = n2.getValue(i);
if(s1>s2 ){
return 1;
}else if(s1<s2){
return -1;
}
}
return 0;
}
Num intToNum32(int value){
Num result = new Num();
int index = 0;
while(index<size){
result.setValue(index, value%maxValue);
value = value/maxValue;
index++;
}
return result;
}
//商可以超出int
Num chu32(Num n1,Num n2){
Num result = new Num();
if(compare(n1,n2)<1) return result; //return 0
Num low = intToNum32(1);
Num high = intToNum32(2000000000);
while(true){
Num mid = jia(low,chu2(jian(high,low)));
Num temp = cheng(n2,mid);
int m0 = compare(n1,temp);
int m2 = compare(n1,jia(n2,temp));
if(m0==0||(m0==1&&m2==-1)){// n1=n2*mid || n2*mid < n1 < n2+n2*mid
return mid;
}else if(m0==-1){ //n1<n2*mid
high = mid;
}else if(m2==0){ // n1 = n2+n2*mid
mid.setValue(0, mid.getValue(0)+1);
return mid;
}else if(m2==1){ //n1 > n2+n2*mid
mid.setValue(0, mid.getValue(0)+1);
low = mid;
}
}
}
Num chu2(Num n1){
Num result = new Num();
for (int i = 0; i < size; i++) {
n1.setValue(i, n1.getValue(i)/2);
}
return result;
}
//***********************
}
第K小数
class Heap{
int K; //结果
public Heap(int data[],int k) {
int mdata[] = new int[data.length+1];
for (int i = 0; i < data.length; i++) {
if(count>=k+1&&data[i]<mdata[1]) {
cover(mdata,data[i]);
}else if(count<k+1){
add(mdata,data[i]);
}
}
}
int count = 1;
void add(int mdata[],int key){
mdata[count++] = key;
up(mdata,count-1);
K = mdata[1];
}
void up(int mdata[],int index){
while(index>1){
int p = index/2;
if(mdata[p]<mdata[index]) swap(mdata,p,index);
index = p;
}
}
void cover(int mdata[],int key){
mdata[1] = key;
down(mdata,1);
K = mdata[1];
}
void down(int mdata[],int index){
int l = index*2;
int r = l+1;
int change = index;
while(l<count){
if(mdata[l]>mdata[change]) change = l;
if(r<count&&mdata[r]>mdata[change]) change = r;
if(change==index) break;
swap(mdata,index,change);
index = change;
l = index*2;
r = l+1;
}
}
void swap(int mdata[],int a,int b){
int tmp = mdata[a];
mdata[a] = mdata[b];
mdata[b] = tmp;
}
}
最近点对
public class POJ3714 {
// 不光有点,还要有集合类别标志
static class Point
{
double x,y;
int flag;
}
static double Min(double a,double b)
{
return a>b?b:a;
}
// 求两点之间的距离
static double dis(Point a,Point b)
{
return Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
// 求最近点对
static double close_pair(Point p[], int l,int r )
{
if(r==l+1) {
if(p[l].flag==p[r].flag) return 99999999;
else return dis(p[l],p[r]);
}
else if(r==l+2) {
if(p[l].flag==p[l+1].flag){
if(p[l].flag==p[r].flag) return 99999999;
else return Min(dis(p[l],p[r]),dis(p[l+1],p[r]));
}else {
if(p[l].flag==p[r].flag) return Min(dis(p[l],p[l+1]),dis(p[l+1],p[r]));
else if(p[l+1].flag==p[r].flag) return Min(dis(p[l],p[l+1]),dis(p[l],p[r]));
}
}
int mid = l+((r-l)>>1);
double ans = Min(close_pair(p,l,mid),close_pair(p,mid+1,r));
int count = 0;
for (int i = l; i <= r; i++) {
if(p[i].x>=p[mid].x-ans&&p[i].x<=p[mid].x+ans) temp[count++] = p[i];
}
quick(temp,0,count-1,false);
for (int i = 0; i < count; i++) {
for (int j = i+1; j < count&& j-i-1<8; j++) {
if(temp[i].flag!=temp[j].flag)
ans = Min(ans,dis(temp[i],temp[j]));
}
}
return ans;
}
// static Point p[];
static Point temp[];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i,n,t;
t = sc.nextInt();
while( t-->0 )
{
n = sc.nextInt();
Point p[] = new Point[2*n];
temp = new Point[2*n];
for(i=0;i<n;++i)
{ p[i] = new Point();
p[i].x = sc.nextInt();
p[i].y = sc.nextInt();
p[i].flag=1;
}
for(;i<n+n;++i)
{ p[i] = new Point();
p[i].x = sc.nextInt();
p[i].y = sc.nextInt();
p[i].flag=2;
}
quick(p,0,n+n-1,true);
System.out.printf("%.3f\n",close_pair(p,0,n+n-1));
}
}
static void quick(Point p[],int low,int high,boolean isX){
if(high>low){
int l = low,h = high;
Point x = p[l];
while(h>l){
while(h>l&&compare(p[h],x,isX)) h--;
if(h>l) p[l++] = p[h];
while(h>l&&compare(x,p[l],isX)) l++;
if(h>l) p[h--] = p[l];
}
p[l] = x;
quick(p, low, h-1, isX);
quick(p, l+1, high, isX);
}
}
static boolean compare(Point a,Point b,boolean isX){
if(isX){
return a.x>b.x?true:false;
}else{
return a.y>b.y?true:false;
}
}
}
顺时针旋转
void translate90(int *target){
int tmp[16];
for(int j = 0; j <4; j++){
for(int k = 0; k < 4; k++){
tmp[j*4+k] = target[(3-k)*4 + j];
}
}
for(int i = 0; i <16; i++)
target[i] = tmp[i];
}
int mapping[][][][] ={
{
{{0,0},{0,1},{0,2}}, //0 ,顺时针
{{1,0},{1,1},{1,2}},
{{2,0},{2,1},{2,2}}
},
{
{{2,0},{1,0},{0,0}}, //90
{{2,1},{1,1},{0,1}},
{{2,2},{1,2},{0,2}}
},
{
{{2,2},{2,1},{2,0}}, //180
{{1,2},{1,1},{1,0}},
{{0,2},{0,1},{0,0}}
},
{
{{0,2},{1,2},{2,2}}, //270
{{0,1},{1,1},{2,1}},
{{0,0},{1,0},{2,0}}
}
};
private void finalRotate() {
rotation%=4;
int tmpBlock[][] = new int[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
tmpBlock[i][j] = block[mapping[rotation][i][j][0]][mapping[rotation][i][j][1]];
}
}
block = tmpBlock;
}
方块,消消乐,俄罗斯方块 -ok
static void fillEmpty(int map[][]){ //向下填补空白(值为0算空白)
for (int i = 0; i < n; i++) {
int bottom = -1;
int count=0;
int j = 0;
while(j < height[i]&& map[j][i]!=0) j++;
bottom = j;
for (; j < height[i]; j++) {
if(map[j][i]==0) count++;
else{
map[bottom][i] = map[j][i];
bottom++;
}
}
height[i]-=count;
}
}
static void moveDown(char map[][]){ //向下填补空白(值为0算空白)
int f0 = 9,f1 = 9; //起始值
for (int y = 0; y < 15; y++) { //横向的遍历方向
while(f0>=0&&f1>=0){
//find first 0
while(f0>=0&&map[f0][y]!=0) f0--; //纵向的遍历方向,本例是↓→坐标系
f1 = f0;
while(f1>=0&&map[f1][y]==0) f1--;
//交换f1 ,f0
if(f0>=0&&f1>=0){
char tmp = map[f0][y];
map[f0][y] = map[f1][y];
map[f1][y] = tmp;
}
}
f0 = 9;
f1 = 9;
}
}
void down(){
int k;
for(int j = 1; j <= rightLimited; j++){
k = -1;
for(int i = 1; i <= height[j]; i++){
if(map[i][j] != 0){
map[k][j] = map[i][j];
k++;
}
}
height[j] = k;
}
}
查表
八方向:
int dx8[] = {1,1,0,-1,-1,-1,0,1}; //↑→
int dy8[] = {0,1,1,1,0,-1,-1,-1};//↑→
//-----------------------------------------
int dx8[] = {-1,-1,0,1,1,1,0,-1}; //↓→
int dy8[] = {0,1,1,1,0,-1,-1,-1};//↓→
四方向:
int dx4[] = {1,0,-1,0}; //↑→
int dy4[] = {0,1,0,-1};//↑→
//--------------------------------
int dx4[] = {-1,0,1,0}; //↓→
int dy4[] = {0,1,0,-1};//↓→
顺时针旋转
int mapping[][][] ={ {{0,0},{0,1},{0,2}, {1,0},{1,1},{1,2}, {2,0},{2,1},{2,2}},
{{2,0},{1,0},{0,0}, {2,1},{1,1},{0,1}, {2,2},{1,2},{0,2}},
{{2,2},{2,1},{2,0}, {1,2},{1,1},{1,0}, {0,2},{0,1},{0,0}},
{{0,2},{1,2},{2,2}, {0,1},{1,1},{2,1}, {0,0},{1,0},{2,0}}
};
求一个数的所有因子(预处理打表) ——OK
对于求一个数n的所有因数和,可能很多人的第一想法是遍历1~sqrt(n)来找其因数,但是这样做不好的地方就是我们可能会遍历大量没有用的数,浪费了很多时间,所以我们与其是求一个数的所有因数和不如求一个数在一个范围内是哪些数的因数,这样求解就可以省去大量的时间,从而达到预处理打表的效果
static int size = 1000000+1;
static long fx[] = new long[size]; //所有的因子的和: fx[6] = 1+3
static long sum[] = new long[size]; //累计和:sum[3]= sum[1]+sum[2]+sum[3];
static void oddSum(){
for (int i = 1; i < fx.length; i++) {
for (int j = 1; j*i < fx.length; j++) {
fx[j*i]+=i;
}
}
for (int i = 1; i < fx.length; i++) {
sum[i] = sum[i-1]+fx[i];
}
}
最大公约数 ——OK
static int getMaxD(int dx,int dy){
int tmp=0,a = dx,b = dy;
while(b!=0) { /* 余数不为0,继续相除,直到余数为0 */
tmp=a%b; a=b; b=tmp;
}
return a;
}
闰年判定
润年的判定方法如下:
若year<1582,则year%4==0 为润年,否则为平年
若year>=1582,则year%4==0 && year%100!=0 ||year%400==0 为润年,否则为平年,注意1700规定为润年。
青蛙
#define MAX_NUM 300005
typedef struct _node
{
int x;
int y;
int fly;
} node;
int N, K;
node graph[MAX_NUM];
int fly[MAX_NUM];
int max;
void qsort(int s, int e)
{
int x = s;
int i, j, tmpx, tmpy;
node tmp;
if (s < e)
{
i = s;
j = e;
int xx = graph[s].x;
int yy = graph[s].y;
tmp = graph[s];
while(i!=j)
{
while(j > i && (graph[j].y + graph[j].x >= xx + yy))
j--;
if (i < j)
graph[i++] = graph[j];
while(j > i && (graph[i].y + graph[i].x <= xx + yy))
i++;
if (i < j)
graph[j--] = graph[i];
}
graph[i] = tmp;
qsort(s, i-1);
qsort(i+1, e);
}
}
int main(void)
{
int test_case;
int T, x, y, f, si, ei;
node start, end;
//freopen("input.txt", "r", stdin);
setbuf(stdout, NULL);
scanf("%d", &T);
for (test_case = 1; test_case <= T; ++test_case)
{
int ex[MAX_NUM], ey[MAX_NUM];
int p, i;
scanf("%d%d", &N, &K);
for (i = 1; i <= N; i++)
{
scanf("%d%d%d", &x, &y, &f);
graph[i].x = x;
graph[i].y = y;
graph[i].fly = f;
}
start.x = graph[1].x;
start.y = graph[1].y;
end.x = graph[N].x;
end.y = graph[N].y;
qsort(1, N); //快排
//获取起点
for (i = 1; i <=N ; i++)
{
if (graph[i].x == start.x && graph[i].y == start.y)
{
si = i;
break;
}
}
//获取终点
for (i = 1; i <=N ; i++)
{
if (graph[i].x == end.x && graph[i].y == end.y)
{
ei = i;
break;
}
}
for (i = 0; i < MAX_NUM ; i++)
{
ex[i] = 0;
ey[i] = 0;
}
ex[graph[si].x] = graph[si].fly;//青蛙从左边跳过来的能量剩余
ey[graph[si].y] = graph[si].fly;//青蛙从上边跳过来的能量剩余
p = si;
while(p != ei)
{
int tmpx, tmpy;
p++;
if (p == ei)
break;
tmpx = ex[graph[p].x]; tmpy = ey[graph[p].y];
if (ex[graph[p].x] >= K)
{
int u = ex[graph[p].x] + graph[p].fly - K;
if (tmpx < u)
tmpx = u;
if (tmpy < u)
tmpy = u;
}
if (ey[graph[p].y] >= K)
{
int u = ey[graph[p].y] + graph[p].fly - K;
if (tmpx < u)
tmpx = u;
if (tmpy < u)
tmpy = u;
}
ex[graph[p].x] = tmpx;
ey[graph[p].y] = tmpy;
}
max = 0;
if (ex[graph[ei].x] + graph[ei].fly - K > max)
max = ex[graph[ei].x] + graph[ei].fly - K;
if (ey[graph[ei].y]+ graph[ei].fly - K > max)
max = ey[graph[ei].y]+ graph[ei].fly - K;
printf("#%d %d\n", test_case, max);
}
return 0; //Your program should return 0 on normal termination.
}
判断两条线段是否相交
“` java
///————alg 3————
double determinant(double v1, double v2, double v3, double v4) // 行列式
{
return (v1*v3-v2*v4);
}
bool intersect3(Point aa, Point bb, Point cc, Point dd)
{
double delta = determinant(bb.x-aa.x, cc.x-dd.x, bb.y-aa.y, cc.y-dd.y);
if ( delta<=(1e-6) && delta>=-(1e-6) ) // delta=0,表示两线段重合或平行
{
return false;
}
double namenda = determinant(cc.x-aa.x, cc.x-dd.x, cc.y-aa.y, cc.y-dd.y) / delta;
if ( namenda>1 || namenda<0 )
{
return false;
}
double miu = determinant(bb.x-aa.x, cc.x-aa.x, bb.y-aa.y, cc.y-aa.y) / delta;
if ( miu>1 || miu<0 )
{
return false;
}
return true;
}
///————alg 3————
“` java