双指针,二分,模拟,贪心经典题目

目录

  • 1244 Estrella's Chocolate
  • 1262 Fish
  • 1269 Craftman
  • 1275 Exam Schedule
  • 1287 银行
  • 1305 斐波那契区间
  • 1344 最长连续子串
  • 1348 数字
  • 1368 substring
  • 1381 表格
  • 1382 正方形
  • 1388 积木
  • 1407 Alice and Bob
  • 1408 Cow
  • 1414 累加和
  • 1417 String II
  • 1419 Balls
  • 1423 三角形
  • 1427 Range
  • 1432 Cycle

1244 Estrella’s Chocolate

题目描述
Estrella是个漂亮的小姑娘,她最喜欢吃的零食就是巧克力,但是巧克力吃多了会发胖,美貌和美食之间她必须做出艰难地选择。
Estrella有N颗巧克力,她按照喜欢的程序给巧克力排好序,并决定在M天内吃完这些巧克力。由于一颗巧克力如果不一次吃完,味道就会变坏,所以她绝对不会把一颗巧克力分开吃。但是每颗巧克力的热量并不相同,Estralla希望知道M天中每天吃的巧克力热量总和最大值。为了尽可能防止发胖,她希望这个值越小越好,请问这个值最小是多少?

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。
每个样例的第一行是两个整数N,M(1≤M≤N≤10000)。
每个样例的第二行是N个整数,表示每颗巧克力的热量,其值处于[1,100000] 之间。

输出
每行输出一个样例的结果。

样例输入
2
5 2
5 3 2 4 1
5 3
5 3 2 4 1
样例输出
8
5

import java.io.*;

public class Main {
    static int n,m,day;
    public static void main(String[] args) throws IOException {
        StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw=new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        int t=(int)in.nval;
        while(t-->0) {
        	in.nextToken();
        	int n=(int)in.nval;
        	in.nextToken();
        	int m=(int)in.nval;
        	int a[]=new int [n];
        	int l=0,r=0;
        	for(int i=0;i<n;i++) {
        		in.nextToken();
        		a[i]=(int)in.nval;
        		r+=a[i];
        	//	l=Math.max(l, a[i]);
        	}
        	while(l<=r) {//左闭右闭
        		int day=1;
        		int sum=0;
        		int mid=(l+r)/2;
        		for(int i=0;i<n;i++) {
        			if(sum+a[i]<=mid) {
        				sum+=a[i];
        			}
        			else {
        				day++;
        				sum=a[i];
        			}
        		}
        		if(day>m) {
        			l=mid+1;
        		}
        		else {
        			r=mid-1;
        		}
     		
        		
        	}
        	pw.println(l);
        	pw.flush();   
        	/*
        	 * 得想想要输出的是什么
        	 */
        }
        
    }

}

1262 Fish

钓鱼
题目描述
小明很喜欢钓鱼,现在有n个池塘可以钓鱼,第i个池塘首次内能钓到ai条鱼。 第i个池塘如果被钓过k次,那么每次下一次能钓到的鱼的数目为max{0,ai−k×bi}。 现在小明能钓m次鱼,请问他最多能钓到多少条鱼?

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。
每个样例的第一行是n(1≤n≤1000),m(1≤m≤100000);
以后的n行,每行是ai(1≤ai≤10000),bi(0≤bi≤10000)。

输出
每行输出一个样例的结果。

样例输入
2
3 5
3 1
4 2
1 0
2 5
2 1
1 1
样例输出
12
4
样例解释
第一个样例,在第1个池塘钓3次,第2个池塘钓2次,3+2+1+4+2 = 12;
第二个样例,在第1个池塘钓2次,第2个池塘钓1次,2+1+1 = 4。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;

public class Main {
    
    static class Node{
        int a;
        int b;
    }
    
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        int t=(int)in.nval;
        while(t!=0) {
            Queue<Node> queue = new PriorityQueue<>(new Comparator<Node>() {

                @Override
                public int compare(Node o1, Node o2) {
                    // TODO Auto-generated method stub
                    return o2.a-o1.a;
                }

            });
            
            
            in.nextToken();
            int n=(int)in.nval;
            in.nextToken();
            int m=(int)in.nval;
            //Node node=new Node();每次存进queue的都是同一个node地址
            for(int i=0;i<n;i++) {
                Node node=new Node();//这里node每次循环都是新的,
                in.nextToken();
                node.a=(int)in.nval;
                
                in.nextToken();
                node.b=(int)in.nval;
                queue.add(node);//存进去的是node的地址。
            }
            
            int ans=0;
            while(!queue.isEmpty()) {
                Node no =queue.poll();
                if(no.b==0) {
                    ans+=no.a*m;
                    break;
                }
                else if(no.a==0){
                    break;
                }
                else {
                    ans+=no.a;
                    no.a=Math.max(0,no.a-no.b);
                    queue.add(no);
                    m--;
                }
                if(m==0) {
                    break;
                }

            }
            pw.println(ans);
            pw.flush();
            t--;
        }
        
    

    }
}

1269 Craftman

Craftsman
题目描述
Alice是游戏中的一名工匠,游戏中最近“恶魔手套”很热,她准备做一批,正好可以赚一笔。 制作一件“恶魔手套”需要n种原材料,第i种原料需要ai份,Alice已经有第i种原料bi份。 Alice还有k份兑换券,兑换券可以去商店兑换任意的原料,但一份兑换券只能兑换一份。请问Alice最多可以制作多少件“恶魔手套”。

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。
每个样例的第一行是n(1≤n≤1000),k(0≤k≤109), 第二行是ai(1≤ai≤109),第三行是bi(0≤bi≤109)。

输出
每行输出一个样例的结果。

样例输入
4
1 1000000000
1
1000000000
1 1
3
1
3 1
1 2 3
3 5 9
3 2
1 2 3
3 5 8
样例输出
2000000000
0
3
3

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
	static long k;
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t-->0) {
			in.nextToken();
			int n=(int)in.nval;
			in.nextToken();
			k=(long)in.nval;
			long a[]=new long [n];
			long b[]=new long [n];
			for(int i=0;i<n;i++) {
				in.nextToken();
				a[i]=(long)in.nval;

				
			}
			for(int i=0;i<n;i++) {
				in.nextToken();
				b[i]=(long)in.nval;
			}
			long l=0,r=(long) (2e9+5);
			/*
			 * 注意int与long的区别,防止溢出
			 * 
			 */
			while(l<=r) {//尽量写成左闭右闭
				long mid=(l+r)/2;
				if(f(k,mid,a,b))
					l=mid+1;
				else r=mid-1;
				
			}
			if(!f(k,l,a,b))l--;
			pw.println(l);
			pw.flush();
		}
	}
	static boolean f(long s,long x,long a[],long b[]) {
	//	long s=k;//直接对全局变量进行运算就会导致全局变量的改变,间接就不会
		for(int i=0;i<a.length;i++) {
			s-=Math.max(0, a[i]*x-b[i]);
			if(s<0)return false;
		}
		return true;
	}

}

1275 Exam Schedule

题目描述
Eric每次考试最头痛的就是安排考试时间,需要找合适的空闲时间安排考试真的是件很费神的事情。
Eric希望你能帮他算一下能哪些时间可以考试,当然Eric并不想周末进行考试,所以你只需要计算周1到周5的时间就可以了。 我们假设每天有11节课的时间,上午1到4节,下午5-8节,晚上9-11节。Eric已经拿到了参加考试的班级的课表,以及考试需要的时长。注意:考试只能安排在上午、下午、晚上时段,不能跨区间。

输入
第一行是一个整数K(1≤K≤100),表示样例的个数
每个样例的第一行是两个整数N(1≤N≤100),T(2≤T≤4),分别表示这些班级课表的条目数和考试所需的课程节数。为了简化问题,Eric只留下了课表条目的上课时间。
以后的N行,每行一个课程的时间,为三个值,D(D∈{Mon,Tue,Wen,Thur,Fri,Sat,Sun}),S,E(1≤S≤E≤11),分别表示上课时间为星期D的第S节到第E节。

输出
每个样例先输出一行,为每个样例合适考试的不同时间段的个数。 然后按时间先后顺序,每行输出一个时间段,分别为S,D,E,中间用一个空格隔开。

样例输入
1
10 3
Mon 1 2
Tue 1 2
Wen 1 2
Thur 1 2
Fri 1 2
Mon 5 6
Tue 5 6
Wen 5 6
Thur 5 6
Fri 5 6
样例输出
5
Mon 9 11
Tue 9 11
Wen 9 11
Thur 9 11
Fri 9 11

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
    static int k,n,t,s,e;
    static String st;
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        k=(int)in.nval;
        while(k!=0) {
            in.nextToken();
            n=(int)in.nval;
            in.nextToken();
            t=(int)in.nval;
            int [][] a=new int [6][12];
            for(int i=0;i<n;i++) {
                in.nextToken();
                st=in.sval;
                in.nextToken();
                s=(int)in.nval;
                in.nextToken();
                e=(int)in.nval;
                if(st.equals("Mon")) {
                    for(int j=s;j<=e;j++) {
                        a[1][j]=1;
                    }
                }
                else if(st.equals("Tue")) {
                    for(int j=s;j<=e;j++) {
                        a[2][j]=1;
                    }
                }
                else if(st.equals("Wen")) {
                    for(int j=s;j<=e;j++) {
                        a[3][j]=1;
                    }
                }
                else if(st.equals("Thur")) {
                    for(int j=s;j<=e;j++) {
                        a[4][j]=1;
                    }
                }
                else if(st.equals("Fri")) {
                    for(int j=s;j<=e;j++) {
                        a[5][j]=1;
                    }
                }
            }
            int ans=0;
            int[][] aa=new int [1000][2];
            for(int i=1;i<=5;i++) {
                int tmp=0;
                for(int j=1;j<=4;j++) {
                    if(a[i][j]==0) {
                        tmp++;
                        if(tmp>=t) {
                            aa[ans][0]=i;
                            aa[ans++][1]=j-t+1;
                        }
                    }
                    else {
                        tmp=0;
                    }
                }
                tmp=0;
                for(int j=5;j<=8;j++) {
                    if(a[i][j]==0) {
                        tmp++;
                        if(tmp>=t) {
                            aa[ans][0]=i;
                            aa[ans++][1]=j-t+1;
                        }
                    }
                    else {
                        tmp=0;
                    }
                }
                tmp=0;
                for(int j=9;j<=11;j++) {
                    if(a[i][j]==0) {
                        tmp++;
                        if(tmp>=t) {
                            aa[ans][0]=i;
                            aa[ans++][1]=j-t+1;
                        }
                    }
                    else {
                        tmp=0;
                    }
                }
            }
            pw.println(ans);
            pw.flush();
            for(int i=0;i<ans;i++) {
                if(aa[i][0]==1) {
                    pw.println("Mon "+aa[i][1]+" "+(aa[i][1]+t-1));
                    pw.flush();
                }
                else if(aa[i][0]==2) {
                    pw.println("Tue "+aa[i][1]+" "+(aa[i][1]+t-1));
                    pw.flush();
                }
                else if(aa[i][0]==3) {
                    pw.println("Wen "+aa[i][1]+" "+(aa[i][1]+t-1));
                    pw.flush();
                }
                else if(aa[i][0]==4) {
                    pw.println("Thur "+aa[i][1]+" "+(aa[i][1]+t-1));
                    pw.flush();
                }
                else if(aa[i][0]==5) {
                    pw.println("Fri "+aa[i][1]+" "+(aa[i][1]+t-1));
                    pw.flush();
                }
            }
            k--;
        }
    }

}

1287 银行

Bank
题目描述
银行使用取号系统来排队提供服务,假设只有一个服务窗口。 用户从s时刻开始取号,业务需要办理t时间,如果在等待d分钟之后仍然没有轮到该用户办理,用户就会走掉。 用户分为两种,一种是普通客户,一种是VIP客户。 VIP客户的优先级高于普通客户,如果同时有多位客户在等待,优先VIP客户。同类客户按取号的时间顺序先到先服务。 不考虑叫号的等待时间,请计算出每个客户的等待时长。

输入
只有一个样例。
每行一个用户的信息,包括用户ID,取号时刻s,办理时长t,最长等待时间d,用户数不超过200人次。
用户ID首字母是由一个字母和四位数字组成,第一个字母如果是大写字母N,表示用户是普通客户,第一个字母是大写字母V,表示用户是VIP客户。
时刻使用"HH24:MM"格式,办理时长和等待时长单位为分钟
输入数据保证所有取号时间都唯一,且按取号时间升序排列,所有的业务在当天办理完成。

输出
按客户的取号时间顺序,输出用户ID和等待时长(时长使用分钟为单位),是否办理业务,如果成功办理,输出Yes,否则输出No

样例输入
N0001 09:00 5 3
N0002 09:01 10 4
V0001 09:02 5 5
N0003 09:03 5 12
V0002 09:04 5 6
样例输出
N0001 0 Yes
N0002 4 No
V0001 3 Yes
N0003 12 Yes
V0002 6 Yes

import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	static int t;
	static Node first=new Node();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner(System.in);
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		Queue<Node>  nnode=new LinkedList<Node>();
		Queue<Node>  vnode=new LinkedList<Node>();//注意这里很离谱		
		Queue<Node>  out=new LinkedList<Node>();
		
		int a[]=new int [250];
		int x=0;
		while(in.hasNext()) {
			Node node =new Node();
			node.st=in.next();
			node.hhmm=in.next();//别用in.nextLine()
			for(int i=0;i<5;i++) {
				if(i==0)
				node.m=(node.hhmm.charAt(i)-'0')*10*60;
				else if(i==1) {
					node.m+=(node.hhmm.charAt(i)-'0')*60;
				}
				else if(i==3) {
					node.m+=(node.hhmm.charAt(i)-'0')*10;
				}
				else if(i==4) {
					node.m+=(node.hhmm.charAt(i)-'0');
				}
			}
			a[x++]=node.m;
			
			node.t=in.nextInt();
			node.d=in.nextInt();
			if(node.st.charAt(0)=='N') {
				nnode.add(node);
			}
			else{
				vnode.add(node);
			}
			
		}
		boolean flag;
		if(!vnode.isEmpty()&&!nnode.isEmpty()&&nnode.peek().m<vnode.peek().m) {//
			first=nnode.poll();
		}
		else if(!vnode.isEmpty()&&!nnode.isEmpty()&&nnode.peek().m>=vnode.peek().m) {
			first=vnode.poll();
		}
		else if(!nnode.isEmpty()){
			first=nnode.poll();

		}
		else if(!vnode.isEmpty()) {
			first=vnode.poll();
		}
		
		int time=first.m;
		int yn=0;
		while(!nnode.isEmpty()||!vnode.isEmpty()) {
			if(first.m!=-1) {

					Node zan=new Node();
					zan.st=first.st;
					zan.wait=0;
					zan.yes="Yes";
					zan.m=first.m;
					out.add(zan);
					time+=first.t;
				
				first.m=-1;
			}
			else if(first.m==-1) {
				if(!nnode.isEmpty()&&!vnode.isEmpty()) {
					Node nn=(vnode.peek().m<=time)?vnode.poll():nnode.poll();//改为time
					yn=nn.m+nn.d;
					if(yn>=time) {
						Node zan=new Node();
						zan.st=nn.st;
						
						if(time-nn.m<0) {
							time=nn.m+nn.t;
							zan.wait=0;
						}
						else {
							zan.wait=time-nn.m;							
							time+=nn.t;

						}
						zan.yes="Yes";
						zan.m=nn.m;
						out.add(zan);
						
					}
					else {
						Node zan=new Node();
						zan.st=nn.st;
						zan.wait=nn.d;
						zan.yes="No";
						zan.m=nn.m;
						out.add(zan);

				
					}
				}
				else if(!nnode.isEmpty()) {
					Node nn=nnode.poll();
					yn=nn.m+nn.d;
					if(yn>=time) {
						Node zan=new Node();
						zan.st=nn.st;
						if(time-nn.m<0) {
							time=nn.m+nn.t;
							zan.wait=0;
						}
						else {
							zan.wait=time-nn.m;							
							time+=nn.t;

						}
						zan.yes="Yes";
						zan.m=nn.m;
						out.add(zan);
					}
					else {
						Node zan=new Node();
						zan.st=nn.st;
						zan.wait=nn.d;
						zan.yes="No";
						zan.m=nn.m;
						out.add(zan);
				
					}					
				}
				else if(!vnode.isEmpty()) {
					Node nn=vnode.poll();
					yn=nn.m+nn.d;
					if(yn>=time) {
						Node zan=new Node();
						zan.st=nn.st;
						if(time-nn.m<0) {
							time=nn.m+nn.t;
							zan.wait=0;
						}
						else {
							zan.wait=time-nn.m;							
							time+=nn.t;

						}
						zan.yes="Yes";
						zan.m=nn.m;
						out.add(zan);
					}
					else {
						Node zan=new Node();
						zan.st=nn.st;
						zan.wait=nn.d;
						zan.m=nn.m;
						zan.yes="No";
						out.add(zan);
					}					
				}
			}
		}
		for(int i=0;i<x;i++) {
			for(Node g:out) {
				if(g.m==a[i]) {
					pw.println(g.st+" "+g.wait+" "+g.yes);
					pw.flush();
				}
			}
		}

		
	}
	static class Node{
		String st;
		String hhmm;
		int m;
		int t;
		int d;
		int wait;
		String yes;
	}
}

1305 斐波那契区间

题目描述
一个数列a1,a2,⋯,an,如果对于区间[L,R],1≤L≤R≤n,∀i(L≤i≤R−2),ai+2=ai+1+ai,那么我们称其为斐波那契区间。求数列中最长的斐波那契区间长度。

输入
第一行是一个整数T(1≤T≤1000),表示样例的个数。
每个样例有两行,第一行是数列的元素个数n(2≤n≤10000)。
第二行是n个整数ai(0≤ai≤109)。

输出
每行输出一个样例的结果。

样例输入
2
10
1 2 3 5 8 13 21 34 55 89
5
1 1 1 1 1
样例输出
10
2

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        int t=(int)in.nval;
        while(t!=0) {
            in.nextToken();
            int n=(int)in.nval;
            long []a=new long[n];
            for(int i=0;i<n;i++) {
                in.nextToken();
                a[i]=(long)in.nval;
            }
            int ans=2;
            int tem=2;
            for(int i=2;i<n;i++) {//双指针太复杂了。还是单指针好用
                if(a[i]==a[i-1]+a[i-2]) {
                    tem++;
                    ans=Math.max(ans,tem);
                }
                else {
                    tem=2;
                }

                    
                
            }
            pw.println(ans);
            pw.flush();
            t--;
        }
    }
    
}
#include
int max(int a,int b)
{
    return a>b ? a : b;
} 

int main()
{
    int k;
    scanf("%d",&k);
    while(k--)
    {
        int n;
        int a[10001];
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        
        int ans=2;
        int l=1,r=3;
        while(l<=n&&r<=n)
        {
            if(a[r]==a[r-1]+a[r-2])
            {
                ans=max(ans,r-l+1);
                r++;
            }
            else
            {
                
                l=r-1;
                r++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

1344 最长连续子串

最长连续子串
题目描述
给一个字符串s=“a1a2a3…an”,如果存在区间[L,R],L≤i

输入
存在多个输入样例,每个样例占一行,为一个长度不超过1000的,只含小写英文的字符串。

输出
每行依次输出每个样例的结果。

样例输入
abc
ababbac
a

样例输出
3
2
1

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        Scanner in=new Scanner(System.in);
        StreamTokenizer hh =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
        while(in.hasNext()) {
            String a=in.next();
            int ans=1;
            int tem=1;
            for(int i=1;i<a.length();i++) {//双指针太复杂了。还是单指针好用
                if(a.charAt(i)==a.charAt(i-1)+1) {
                    tem++;
                    ans=Math.max(ans,tem);
                }
                else {
                    tem=1;
                }

                    
                
            }
            pw.println(ans);
            pw.flush();
        }
    }
    
}

1348 数字

数字
题目描述
正整数n和k,你每一步,按下列规则执行

如果n的尾部为数码0,就去掉尾部的数码0,直到尾部数码不为0。
否则,将 n = n - k
不断迭代,直到 n < k 。

求一共需要迭代多少步及最后的n值。

输入
第一行是一个整数T(1≤T≤1000),表示样例的个数。 以后每行一个样例,为两个整数n(1≤n≤109),k(1≤k≤104)

输出
每行输出一个样例的结果,包括两个整数,即步数和最后的n值。

样例输入
4
112 3
203 3
333 3
1000000000 2
样例输出
5 1
2 2
5 0
1 1
样例解释
第1个样例: 112→109→106→103→100→1。
第2个样例: 203→200→2。
第3个样例: 333→330→33→30→3→0。
第4个样例: 1000000000→1。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
	static long [] a=new long [10];
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t!=0) {
			long ans=0;
			in.nextToken();
			long n=(long)in.nval;
			in.nextToken();
			long k=(long)in.nval;
			for(int i=1;i<=9;i++) {
				a[i]=k*i%10;
			}
			while(n>=k) {
				if(n%10==0) {
					while(n%10==0) {
						n=n/10;
					}
					ans++;
				}
				else {
					int flag=0;
					for(int i=1;i<10;i++) {
						if(n%10==a[i]) {
							
							if(n>k*i) {//得加上正数的限制条件
								n-=k*i;
								ans+=i;
								flag=1;
								break;
							}
							else {
								ans+=n/k;
								n=n%k;
								break;
							}
							
							
							
						}
					}
					if(flag==0) {
						ans+=n/k;//
						n=n%k;
					}
				}
				
			}
			pw.println(ans+" "+n);
			pw.flush();			
			t--;
		}
	}

}

1368 substring

题目描述
一个字符串s=a1a2…an,其子串为s′=aiai+1…ak,1≤i≤k≤n。 我们相求其最短的子串的长度,子串中含所有26个英文字母。

输入
存在多组样例,样例数不超过1000个。
每行输入一行字符串,长度不超过2000个字符,且只含小写英文字母。

输出
每行输出一个样例的结果。如果不存在这样的子串,输出0。

样例输入
abcdefghijklmnopqrstuvwxyz
abacadaeafagahaiajakalamanaoapaqarasatauavawaxayaz
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
样例输出
26
49
0

import java.util.HashSet;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Scanner in=new Scanner(System.in);
			while(in.hasNext()) {
				String st=in.next();
				int ans=100000;
				int[] a=new int [26];
				HashSet<Character>set=new HashSet<>();
				for(int i=0;i<st.length();i++) {
					a[st.charAt(i)-'a']=i;					
					if(set.size()!=26) {
						set.add(st.charAt(i));

					}
					if(set.size()==26){//注意两个if
						int max=0,min=100000;
						for(int j=0;j<26;j++) {
							max=Math.max(max, a[j]);
							min=Math.min(min, a[j]);
						}
						ans=Math.min(max-min+1, ans);
					}
					
				}
				if(set.size()<26) {
					ans=0;
				}
				System.out.println(ans);
			}
	}
}

1381 表格

表格
题目描述
用户输入一个表格的文本,请按如下格式输出:

  1. 用’-‘表示横线,’|‘表示竖线,’+'表示横竖线的交点
  2. 列宽为当前列最长字符串长度+2
  3. 每列的对齐方式相同,一共有三种,分别为靠左对齐,居中对齐,靠右对齐,分别用’l’,‘c’,'r’表示。
    a. 靠左对齐,字符串左端距离边线1个空格;
    b. 居中对齐,字符串距离边线左和右空格数的差不超过1,且左边空格数小于等于右边空格数。
    c. 靠右对齐,字符串右端距离边线1个空格;
    输入
    第一行是一个整数T(1≤T≤100) , 表示样例的个数。

每个样例的第1行是两个整数r,c(1≤r,c≤10),表示表格的行和列数。
第2行是c个字符,字符只由’l’,‘c’,'r’三种组成,依次表示对应列的对齐方式。
以后的r行,每行c个字符串,表示对应行列的单元格内容,字符串只含英文字母,数字,长度不超过20个字符。

输出
按格式依次输出每个样例的的结果。

样例输入
1
3 5
lcccr
Name English Math Chinese Total
Alice 100 85 75 260
Bob 85 100 85 270
样例输出
±------±--------±-----±--------±------+
| Name | English | Math | Chinese | Total |
±------±--------±-----±--------±------+
| Alice | 100 | 85 | 75 | 260 |
±------±--------±-----±--------±------+
| Bob | 85 | 100 | 85 | 270 |
±------±--------±-----±--------±------+

1382 正方形

由火柴棍组成的一个n×n的正方形,按从上到下,从左到右的顺序给火柴棍编号,从1开始,比如下图中,一共有24根火柴棍。 问去掉若干个火柴棍之后,这个图形中还存在多少个正方形?

如下图所示,n=3时,去掉12,17,23号火柴棒之后,还剩下5个正方形。

双指针,二分,模拟,贪心经典题目_第1张图片

输入
第一行是一个整数T(1≤T≤1000),表示样例的个数。

每个样例的第1行是两个整数n(1≤n≤50),表示图形的宽度。 样例的第2行首先是一个整数m(0≤m≤2n(n+1),表示去掉火柴棍的个数,后面接m个整数,表示去掉火柴棍的序号,所有序号都是唯一的。

输出
依次,每行输出一个样例的结果

样例输入
2
3
0
3
3 12 17 23
样例输出
14
5

1388 积木

题目描述
积木块都是相同的立方体,一共有n列积木堆,这n列积木排成一排,每堆上是ai个积木堆叠起来,并且保证从左到右,每列的积木数是非递减的。

现在你还有k个积木块,请把这k个积木块放到积木上(可以只用部分积木块,但不能堆新的列)。你想的到一个连续的积木列,并使得这些积木列具有相同的高度。

请问你能得到这样的积木列的最大宽度?

输入格式
第一行是一个整数T (1≤T≤100),表示样例的个数。 每个样例的第一行是两个整数n (1≤n≤10000), k (1≤k≤109)。 第二行是n个正整数ai,1≤ai≤105,表示n列。

输出格式
依次输出每个样例的结果,为一个整数。

样例输入
3
5 0
1 1 2 2 3
5 1
1 1 2 2 3
5 2
1 1 2 2 3
样例输出
2
3
4
样例解释
第一个样例,不能放任何积木块,所以连续同高积木列的宽度为2。
第二个样例,我们可以在第2列上放一个积木块,这样我们得到宽度为3的高度为2的连续同高积木列。
第三个样例,我们可以在第1,2列上各放一个积木块,这样我们得到宽度为4的高度为2的连续同高积木列。

提示
巨大的输入量,请使用stdio.h头文件,并使用C风格的输入。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t!=0) {
			in.nextToken();
			int n=(int)in.nval;
			in.nextToken();
			long k=(long)in.nval;
			int a[]=new int [n];
			for(int i=0;i<n;i++) {
				in.nextToken();
				a[i]=(int)in.nval;
			}
			int ans=1;
			int l=0,r=1,sum=0;
			while(l<n&r<n) {
				if(a[r]!=a[r-1]) {
					sum+=(r-l)*(a[r]-a[r-1]);
				}
				if(sum<=k) {
					ans=Math.max(ans, r-l+1);
					
					
				}		
				while(sum>k) {
					sum-=(a[r]-a[l]);
					l++;
					
				}
		
				r++;
			}

			pw.println(ans);
			pw.flush();
			t--;
		}
	}

}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t!=0) {
			in.nextToken();
			int n=(int)in.nval;
			in.nextToken();
			long k=(long)in.nval;
			int a[]=new int [n];
			for(int i=0;i<n;i++) {
				in.nextToken();
				a[i]=(int)in.nval;
			}
			int ans=1,i=0,size=1,kk=0;
			for(int j=1;j<n;j++) {//其实也是双指针的方法
				size++;				
				if(a[j]!=a[j-1]) {
					kk=kk+(j-i)*(a[j]-a[j-1]);
				}

				while(kk>k) {
					kk=kk-(a[j]-a[i]);
					i++;
					size--;
				}
				if(ans<size) {
					ans=size;
				}
			}
			pw.println(ans);
			pw.flush();
			t--;
		}
	}

}

1407 Alice and Bob

题目描述
Alice和Bob打球,已知他们打过的每一回合的输赢情况,每个回合获胜的一方可以得一分。 Alice可以随意设定赢得一局比赛所需的分数和赢得整个比赛所需要的局数。 Alice想赢得比赛,请问在满足下列条件下,Alice应该怎么设置这两个参数,保证自己能赢?

所有的回合都必须用来计算比赛的结果,即每一局比赛都会完整的结束,不会存在未完成的对局
谁先拿到赢得一局所需的分数就赢得这一局
谁先达到赢得比赛所需的局数就赢得这场比赛
不会出现某一方已经赢得比赛的一局或者整场比赛后,还继续打球的情况
每局胜利所需要的分数是相同
输入
包含不超过1000组样例,每个样例为一行。 每行输入一个只含字母’W’和’L’的字符串,长度不超过200,'W’和’L’分别表示这一回合Alice赢或者输。

输出
每个样例先输出一行,为合法方案的总数。然后按局分,局数的升序,每一行输出一个方案,包括两个整数,即局分和局数。如果Alice无法赢或者没有合法的方案,只需要输出方案数为0即可。

样例输入
LWW
WLWW
LLWW
样例输出
2
1 2
2 1
2
1 3
3 1
0
样例解释
第一个样例:可以每局先得1分者胜,先赢得2局的人获得整场胜利;也可以每局先得2分者胜,先赢得1局的人获得整场胜利。 第二个样例:可以每局先得3分者胜,先赢得1局的人获得整场胜利;也可以每局先得1分者胜,先赢得3局的人获得整场胜利。不能令每局先得2分者胜,先赢得1局的人获得整场胜利,因为那样会留下未完成的对局。 第三个样例:可怜的Alice无论如何也不能赢。

第一个样例的第一种情况是:bob先拿到了1分,赢了一局,之后alice拿到了2分,赢了2局,则取得了比赛的胜利。
第二种情况是:bob先拿到了1分,之后,alice拿到了2分,赢了1局,取得了胜利

1408 Cow

题目描述
农夫约翰有一个农场,他把上面分成了n×m个格子,每个格子里养了一头牛。 但是有p对相邻格子(有共同边的格子)的牛是敌对关系,喜欢打架,约翰想做一些栅栏把他们分开。 所有的栅栏都是沿着边线的,横的或者竖的,每条栅栏都是贯穿整个横边或者竖边的。 但是约翰的预算有限,他想知道最多建k条栅栏使得尽可能减少打架的牛的对数。 比如下图中,相同的字符表示会相互打架的牛,我们可以建3条栅栏(红线),使得所有敌对关系的牛都隔离开。

cow

输入
第一行是一个整数T(1≤T≤400),表示样例的个数。 每个样例的第一行是4个整数n(1≤n≤100),m(1≤m≤100),p(1≤p≤2nm−n−m),k(1≤k≤max(1,n+m−2))。 以后的p行,每行4个整数x1,y1,x2,y2(1≤x1,x2≤m;1≤y1,y2≤n),表示(x1,y1)与(x2,y2)的牛需要分开。输入保证没有重复信息并且输入的都是相邻格。

输出
每行输出一个样例的结果,输出在建立k条栅栏的情况下,还会打架的牛的对数。如果可以完全分隔开牛,那么还需要输出需要建立的最少的栅栏数。

样例输入
2
5 5 3 4
1 2 2 2
2 3 3 3
2 4 2 5

5 5 3 1
1 2 2 2
2 3 3 3
2 4 2 5
样例输出
0 3
2
样例解释
输入的样例即图示,明显第一个样例中只需要3条栅栏就能把所有敌对的牛分开;第二个样例只能分开1对牛,所以还剩2对敌对关系的牛。

提示
巨大的输入量,请使用C风格的输入。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.*;
public class Main {

	/*
	 * 
	 * runtime error大概率是数组越界问题
	 * 遇到runtime error时,把一部分代码注释掉,提交通对比法,比较得出哪一部分出了问题。
	 */
	
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t!=0) {

			in.nextToken();
			int n=(int)in.nval;
			in.nextToken();
			int m=(int)in.nval;
			in.nextToken();
			int p=(int)in.nval;
			in.nextToken();
			int k=(int)in.nval;
			int [] row=new int [105];
			int [] col=new int [105];
			for(int i=0;i<p;i++) {
					in.nextToken();
					int x1=(int)in.nval;
					in.nextToken();
					int y1=(int )in.nval;
					in.nextToken();
					int x2=(int)in.nval;
					in.nextToken();
					int y2=(int)in.nval;
					
					if(x1==x2) {//同一行
						if(y1<y2) {
							col[y1]++;
						}
						else {
							col[y2]++;
						}
					}
					else if(y1==y2) {
						if(x1<x2) {
							row[x1]++;
						}
						else {
							row[x2]++;
						}
					}
			}//前面没问题的
			int shanlan=0;
			int index=0;
			int []buff=new int [200];

			for(int i=0;i<105;i++) {//这里也要由n改成105,才ac。为了确保正确,数组尽量开大点
				if(row[i]!=0) {
					shanlan++;
					buff[index++]=row[i];
				}
			}
			for(int i=0;i<105;i++) {//这里也要由m改成105
				if(col[i]!=0) {
					shanlan++;
					buff[index++]=col[i];			
				}

			}
	        int lanzhu=0;
	        Arrays.sort(buff);
	        for(int i=0;i<k;i++) {
	        	lanzhu+=buff[199-i];//输入的k比buff的最大下标要大,就导致wa
	        }
			if(shanlan<=k) {
				pw.println("0 "+shanlan);
				pw.flush();
			}
			else {
				pw.println(p-lanzhu);
				pw.flush();
			}
			t--;
		}
	}

}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.*;

public class Main {

	/*
	 * 
	 * runtime error大概率是数组越界问题
	 * 遇到runtime error时,把一部分代码注释掉,提交通对比法,比较得出哪一部分出了问题。
	 */

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t!=0) {

			in.nextToken();
			int n=(int)in.nval;
			in.nextToken();
			int m=(int)in.nval;
			in.nextToken();
			int p=(int)in.nval;
			in.nextToken();
			int k=(int)in.nval;
			int [] row=new int [105];
			int [] col=new int [105];
			for(int i=0;i<p;i++) {
					in.nextToken();
					int x1=(int)in.nval;
					in.nextToken();
					int y1=(int )in.nval;
					in.nextToken();
					int x2=(int)in.nval;
					in.nextToken();
					int y2=(int)in.nval;
					
					if(x1==x2) {//同一行
						if(y1<y2) {
							col[y1]++;
						}
						else {
							col[y2]++;
						}
					}
					else if(y1==y2) {
						if(x1<x2) {
							row[x1]++;
						}
						else {
							row[x2]++;
						}
					}
			}//前面没问题的
			int shanlan=0;
			int index=0;
			Integer []buff=new Integer[200];//数组空间大小问题。大小要比k大
			for(int i=0;i<200;i++) {
				buff[i]=0;
			}
			for(int i=0;i<105;i++) {//这里也要由n改成105,才ac。为了确保正确,数组尽量开大点
				if(row[i]!=0) {
					shanlan++;
					buff[index++]=row[i];
				}
			}
			for(int i=0;i<105;i++) {//这里也要由m改成105
				if(col[i]!=0) {
					shanlan++;
					buff[index++]=col[i];			
				}

			}
	        int lanzhu=0;
	        Arrays.sort(buff,Collections.reverseOrder());
	        for(int i=0;i<k;i++) {
	        	lanzhu+=buff[i];//输入的k比buff的最大下标要大,就导致wa
	        }
			if(shanlan<=k) {
				pw.println("0 "+shanlan);
				pw.flush();
			}
			else {
				pw.println(p-lanzhu);
				pw.flush();
			}
			t--;
		}
	}

}

1414 累加和

累加和
题目描述
一个整数数列A={a1,a2,…,an}和k次查询,每次查询值s,求存在多少个区间[L,R],1≤L≤R≤n,使得s=∑Ri=Lai。

输入
第一行是一个整数T(1≤T≤10),表示样例的个数。 每个样例的第一行是两个整数n(1≤n≤10000),k(1≤k≤100)。 每个样例的第二行是n个正整数ai(1≤ai≤10000)。 每个样例的第三行是k个整数,表示k次查询的s值。

输出
每行输出一次查询的结果。

样例输入
2
10 3
1 2 3 1 2 3 1 2 3 4
3 7 9
10 3
1 2 3 4 5 6 7 8 9 10
3 7 9
样例输出
6
3
5
2
2
3

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int t=(int)in.nval;
		while(t--!=0) {
			in.nextToken();
			int n=(int)in.nval;
			in.nextToken();
			int k=(int)in.nval;
			int []a=new int[n];
		    for(int i=0;i<n;i++) {
		    	in.nextToken();
		    	a[i]=(int)in.nval;
		    }
		    while(k--!=0) {
		    	in.nextToken();
		    	int num=(int)in.nval;
		    	int l=0;int r=0;
		    	int sum=0;
		    	int ans=0;
		    	while(r<a.length) {
		    		while(r<a.length&&sum<num) {
		    		sum+=a[r++];
		    		}
		    		if(sum==num) {
		    			ans++;
		    			sum-=a[l++];
		    		}
		    		while(l<r&&sum>num) {
		    			sum-=a[l++];
		    		}
		    		if(sum==num) {
		    			ans++;
		    			sum-=a[l++];
		    		}
		    	}
		    	pw.println(ans);
		    	pw.flush();
		    	
		    }
		}

	}

}

1417 String II

String II
题目描述
一个只含小写英文字母的字符串,每次操作选两种字符,把这两种字符合并成其中一种,每次操作的代价是合并字符个数的平方,请问将字符串变成同一种字符的最小代价?

输入
存在多个输入样例。 每行一个字符串,只含小写英文,长度不超过2000。

输出
每行输出一个样例的结果。

样例输入
aab
abc
aaa
abcd
样例输出
9
13
0
24
样例解释
第一个样例,将a和b合并,代价为32=9;第二个样例,先将a和b合并成a,再将a和c合并成a,代价为22+32=13; 第三个样例无需合并,代价为0。第四个样例,先将a和b合并成a,再将c和d合并成c,最后将a和c合并成a,代价为22+22+42=24

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
        Scanner in=new Scanner(System.in);
        while(in.hasNext()) {
        	String st=in.next();
        	int a[]=new int [26];
        	for(int i=0;i<st.length();i++) {
        		a[st.charAt(i)-'a']++;
        	}
        	Queue <Integer>queue=new PriorityQueue<>();
        	int flag=0;
        	for(int i=0;i<26;i++) {
        		if(a[i]!=0) {
        			queue.add(a[i]);
        			flag++;
        		}
        	}
        	
        	long ans=0;
        	while(!queue.isEmpty()) {
        		int x=queue.poll();
        		int y=0;
        		if(!queue.isEmpty()) {
        			y=queue.poll();
        		}
        		else {
        			break;
        		}
        		ans+=(x+y)*(x+y);
        		queue.add(x+y);
        	}
        	if(flag==1) {
        		pw.println(0);
        		pw.flush();
        	}
        	else {
        		pw.println(ans);
        		pw.flush();
        	}
        }
	}

}

1419 Balls

题目描述
你有若干个彩球排成一列,你可以交换相邻的两个球。 交换后,如果出现包含被交换彩球且长度大于等于3的连续相同颜色彩球,那么这些彩球就会消失,右边的彩球会向左边靠拢填满空间。 现在给你一个操作的序列,请依次输出每次操作后的彩球序列。

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。 每个样例包含两行,第一行是一个字符串,长度不超过30,只含大写字母’A’-‘C’,表示不同字母表示不同颜色的球。第二行开始是一个整数n(1≤n≤10),表示操作的个数,以后n个整数ai表示将ai和ai+1交换。输入数据保证是合法的操作。

输出
每个样例的每行输出一个操作后彩球的状况,如果所有的彩球都消失,输出”Over”。每个样例最后输出一个空行。

样例输入
4
AABABBB
1 3
AAAABBBBC
2 4 4
AAAAAA
1 2
AABAABBB
2 3 1
样例输出
Over

AAABABBBC
C

Over

BABBB
A

1423 三角形

题目描述
我们知道三角形必须满足任意两边之和大于第三边,任意两边之差小于第三边。现在有一个边长的多值集E={e1,e2,…,en},任取三条边,能组成三角形的方案数。

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。

每个样例的第一行是一个整数n(3≤n≤1000),表示边集的大小。 每个样例的第二行是n个正整数ei,1≤ei≤109,表示边长。

输出
每行输出一个样例的结果。

样例输入
3
5
1 2 3 4 5
5
1 1 1 1 1
5
9 1 1 5 3
样例输出
3
10
0

1427 Range

题目描述
一个多值集A={a1,a2,…,an},如果∀x∈A ,满足 x≤c⋅min(A), c是一个大于1的整数常量,min(⋅)表示求多值集的最小值,那么我们称这个集合是“好”的。 现在给你一个多值集,请问最少去掉几个元素,使得多值集是好的?

输入
第一行是一个整数T(1≤T≤100),表示样例的个数。 每个样例的第一行是两个整数n(1≤n≤10000),c(2≤c≤10),分别表示多值集的大小和常数c; 第二行为n个整数ai(1≤ai≤109)。

输出
每行输出一个样例的结果。

样例输入
2
6 2
3 5 4 7 8 3
4 4
1 2 3 4
样例输出
2
0
样例解释
第一个样例,可以去掉两个3,剩下5,4,7,8;或者去掉7和8,剩下3,5,4,3。 第二个样例,不用去掉任何一个元素就满足条件。

提示
巨大的输入数据,请使用C风格的输入。

1432 Cycle

题目描述
数字 1∼n顺时钟排成一个圈,从1开始顺时钟计数,数到的数退出这个圈,然后从下一个数字开始数,直到剩下最后一个数字。 计数的序列为{a1,a2,…,an−1}, 其中 ai=(ai−1+ai−2)%n+1,i>2 且 1≤a1,a2≤n。

比如n=5,计数序列的前两项为{1,2}时,整个计数序列为{1,2,4,2},那么第一次去掉数字1,得到数字圈为{2,3,4,5}; 再从2开始,数两个数,到数字3,去掉得到数字圈为{4,5,2};依次,再数4个数,到数字4,去掉得到数字圈为{5,2};最后数2个数,去掉2,剩下5。

请你写个程序,在已知n,a1,a2的情况下,求最后剩下的数?

输入
第一行是一个整数T(1≤T≤1000),表示样例的个数。

以后每行一个样例,为三个整数n(2≤n≤1000),a1,a2(1≤a1,a2≤n)。

输出
每行输出一个样例的结果。

样例输入
2
3 2 3
5 2 3
样例输出
1
4

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
        StreamTokenizer in =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter pw =new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        int t=(int)in.nval;
        while(t!=0) {
        	t--;
        	in.nextToken();
        	int n=(int)in.nval;
        	int a[]=new int[1005];//如果n==2时,a最大只有1,会造成a[2]的 runtime error
        	int flag[]=new int [n+5];
        	in.nextToken();
        	a[1]=(int)in.nval;
        	in.nextToken();
        	a[2]=(int)in.nval;
        	
        	
        	if(n>2) {
        		for(int i=3;i<=n-1;i++) {//标记
        			a[i]=(a[i-1]+a[i-2])%n+1;
        		}        		
        	}else {
        		if(a[1]==1) {
        			pw.println(2);
        			pw.flush();
        			continue;
        		}
        		else {
        			pw.println(1);
        			pw.flush();
        			continue;
        		}
        	}

        	int j=1;
        	for(int i=1;i<=n-1;i++) {
        		int pos=0;
        		a[i]=a[i]%(n-i+1);//对剩余元素进行取模,不用绕那么多圈
        		if(a[i]==0) {
        			a[i]=n-i+1;
        		}
        		while(a[i]>pos) {
        			if(flag[j]==0) {
        				pos++;
        			}
        			if(j==n) {
        				j=1;
        			}
        			else {
        				j++;
        			}
        		}
        		if(j==1)
        			flag[n]=1;
        		else {
        			flag[--j]=1;
        			j++;
        		}
        	}
        	for(int i=1;i<n+1;i++) {
        		if(flag[i]==0) {
        			pw.println(i);
        			pw.flush();
        			break;
        		}
        	}
        }
	}

}

你可能感兴趣的:(湘潭大学C语言程序设计作业,贪心算法,算法,java)