【質問】Javaの毎日のブラッシング質問1

A.サブ配列をソートする

質問:与えられた配列 (これに基づいて操作された配列) で、操作された最長の非減少連続シーケンスを見つけます。

解決策:この質問を書き始めたときに与えられた例に混乱しました。与えられた例はすべて操作され、非減少シーケンスを持つフラグメントであるため、2 番目の配列に直接アクセスして最長の非減少シーケンスを見つけました。 。しかし、質問の意味には別の意味の層があり、見つかった非減少数列が操作されていない場合、それを答えとして使用することはできません。したがって、2 番目の配列を見るだけでなく、最初の配列を比較してどこで演算されているかを確認し、その中で最長の非減少シーケンスを見つけることもできます。

コード:

import java.util.ArrayList;
import java.util.Scanner;

public class A {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		int tt=0;
		while(t>0) {
			t--;
			tt++;
			int n = cin.nextInt();
			ArrayList<Integer> a = new ArrayList();
			ArrayList<Integer> b = new ArrayList();
			for(int i=0; i<n; i++) {
				int x = cin.nextInt();
				a.add(x);
			}
			for(int i=0; i<n; i++) {
				int x = cin.nextInt();
				b.add(x);
			}
			if(tt==23) {
				System.out.println(n);
				for(int i=0;i<n;i++)System.out.println(a.get(i)+" "+b.get(i));
				break;
			}
			int l=-1,r=-1;
			int ll=-1,rr=-1;
			int flag=0,cnt=0,ans=0;
			for(int i=0; i<n-1; i++) {
				int aa = b.get(i);
				int bb = b.get(i+1);
				if(aa <= bb) {
					cnt++;
					if(a.get(i)!=b.get(i)) {
						flag=1;
					}
					if(cnt==1) {
						l=i+1;
					}
					if(i==n-2) {
						if(cnt>ans && flag==1) {
							ll = l;
							rr = i+2;
							ans=cnt;
						}
					}
				}else if(aa > bb){
					if(cnt>ans && flag==1) {
						ll = l;
						rr = i+1;
						ans=cnt;
					}
//					System.out.println(aa+ " " + bb + " " +ll + " " + rr);
					cnt=0;
					flag=0;
				}
				
			}
			System.out.println(ll + " " + rr);
		}
	}

}

B. 引き裂いてください

質問の意図:指定された文字列に対して k 回の削除操作を実行します。各操作では、n 個の隣接しない文字が削除され、最終的に 1 種類の文字だけが残ります。k の最小数を求めます。

解決策:ここでは、最初に指定された文字列に出現した文字を調べ、次に、出現した文字に基づいて、その文字列と次に出現するまでの間に他の文字の数を調べ、最大値を見つけます。残り この文字に必要な操作の最小数。次に、文字列内のすべての文字を順番に走査します。

コード:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class B {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			t--;
			String s = cin.next();
			int len = s.length();
			Map<Character,Integer> mp = new HashMap<>();
			int []p = new int[10005];
			for(char i:s.toCharArray()) {
				if(mp.containsKey(i)){ //key存在
	                Integer value = mp.get(i);
	                value++;
	                mp.put(i,value);
	            }else{ //key不存在
	                mp.put(i,1);
	            }
			}
			int minn=Integer.MAX_VALUE,cnt=0,sum=0;
			Character ms = new Character('a');
			for(Character key: mp.keySet()) {
				Integer val = mp.get(key); //出现次数
//				System.out.println(key + ": " + val);
				cnt=0;
				for(int i=0; i<len; i++) {
	//				System.out.println(s.charAt(i) +"  " + ms);
					if(s.charAt(i)==key){
						cnt=0;
		            }else{ 
		                cnt++; 
		            }
//					System.out.println(s.charAt(i) +"  " + cnt);
					sum = Math.max(sum, cnt);
				}
				cnt=0;
				while(sum>0) {
					if(sum%2==1) {
						sum = (sum-1)/2; 
						cnt++;
					}else {
						sum /= 2;
						cnt++;
					}
				}
				minn = Math.min(cnt, minn);
			}
			System.out.println(minn);
		}
		cin.close();
	}
}

C.由良の新しい名前

質問の意味: ^^ または ^_^ は笑顔です。^ または _ は一度に 1 つだけ挿入できます。挿入の最小数を見つけてください。

解決策:まず真ん中の連続する _ をたどり、n 個連続する場合は途中に n-1 ^ を挿入し、最初と最後のものを判断し、文字が 1 つしかない場合も判断します。

コード:

import java.util.Scanner;

public class C {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			t--;
			String s = cin.next();
			int len = s.length();
			int cnt=0,k=0;
			if(len==1) {
				if(s.charAt(0)=='^') {
					cnt=1;
				}else if(s.charAt(0)=='_') {
					cnt=2;
				}
			}else if(len==2 && s.charAt(0)=='_' && s.charAt(1)=='_'){
				cnt=3;
			}else {
				for(int i=1; i<len-2; i++) {
					if(s.charAt(i)=='_' && s.charAt(i+1)=='_') {
						k++;
					}else if(s.charAt(i)=='_' && s.charAt(i+1)=='^') {
						cnt+=k;
						k=0;
					}
				}
				cnt+=k;
//				System.out.println(cnt);
				if(s.charAt(0)=='_') {
					if(s.charAt(1)=='^') {
						cnt++;
					}else {
						cnt+=2;
//						System.out.println("****");
					}
				}
				if(s.charAt(len-1)=='_') {
					if(s.charAt(len-2)=='^') {
						cnt++;
					}else {
						cnt+=2;
//						System.out.println("++++");
					}
				}
			}
			System.out.println(cnt);
		}
	}
}

D. ジョジョのインクレディブル・アドベンチャー

タイトルの意味:

答え:

コード:

import java.util.Scanner;

public class D {
	public static void main(String[] args) throws Exception {
		Scanner cin=new Scanner(System.in);
        int t=cin.nextInt();
        cin.nextLine();
        while(t-->0) {
        	String s=cin.nextLine();
            int i=0,j=s.length()-1;
            if(!s.contains("0")){
                long ans= (long) s.length() *s.length();
                System.out.println(ans);
            }
            else{
                long cnt=0,cnt1=0;
                while(s.charAt(i)=='1'){
                    i++;
                    cnt++;
                }
                while(s.charAt(j)=='1'){
                    j--;
                    cnt1++;
                }
                int l=i+1,r=i+1;
                long len=0;
                for(;r<=j;){
                    if(s.charAt(r)=='1') r++;
                    else{
                        len=Math.max(len,r-l);
                        r++;
                        l=r;
                    }
                }
                len=Math.max(len,r-l);
                len=Math.max(len,cnt+cnt1);
                long ans=0,p=1,q=0;
                while(p<=len){
                    q=p*len;
                    ans=Math.max(q,ans);
                    p++;
                    len--;
                }
                System.out.println(ans);
            }
        }
    }
}

E. 建設的な問題

タイトルの意味:

答え:

コード:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class E {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			t--;
			int n = cin.nextInt();
			ArrayList<Integer> a = new ArrayList<>();
			Map<Integer,Integer> mp = new HashMap<>();
			int cnt=0;
			for(int i=0; i<n; i++) {
				int x = cin.nextInt();
				a.add(x);
//				System.out.println(mp.get(x));
				if(mp.get(x)==null||mp.get(x)==0) {
					cnt=1;
				}else {
					cnt = mp.get(x)+1;
				}
				if(cnt==1)
				mp.put(x, cnt);
				else
				mp.replace(x, cnt);
			}
			int mex=-14;
			for(int i=0; i<n; i++) {
				if(mp.get(i)==null||mp.get(i)==0) {
					mex=i;
					break;
				}
			}
			int m = mex+1;
			int be=-1,en=-1;
			int f1=0,f2=0;
			for(int i=0; i<n; i++) {
				if(a.get(i)==m && f1==0) {
					be = i;
					f1=1;
				}
				if(a.get(n-1-i)==m && f2==0) {
					en = n-i-1;
					f2=1;
				}
				if(f1==1 && f2==1) break;
			}
			if(be!=-1||en!=-1) {
			for(int i=be; i<=en; i++) {
				int val = a.get(i);
				int now = mp.get(val)-1;
				mp.replace(val,now);
//				System.out.println(val+ ": "+now);
			}}
			//if(mex<=n-1) {
				mp.put(mex, 1);
			//}
			int newMex=-10;
			for(int i=0; i<=n; i++) {
//				System.out.println(i+"             "+mp.get(i));
				if(mp.get(i)==null || mp.get(i)==0) {
					newMex=i;
					break;
				}
			}
//			System.out.println(m+"  "+newMex);
			if((newMex!=m||mex==n)) {
				System.out.println("No");
			}else {
				System.out.println("Yes");
			}
		}
	}

}

F.リー・ファとメイズ

質問の意味:指定された開始位置が終点に到達しないように、最小の点を取り消してください。

問題の解決策: 4 つの点と、点を除く面に必要な点を判断します。

コード:

import java.util.Scanner;

// F - Li Hua and Maze
public class F {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			int n = cin.nextInt();
			int m = cin.nextInt();
			int x1 = cin.nextInt();
			int y1 = cin.nextInt();
			int x2 = cin.nextInt();
			int y2 = cin.nextInt();
			int cnt=0;
			if((x1==1 && y1==1) || (x1==n && y1==1) || (x1==1 && y1==m) || (x1==n && y1==m)) {
				cnt=2;
			}else if((x2==1 && y2==1) || (x2==n && y2==1) || (x2==1 && y2==m) || (x2==n && y2==m)) {
				cnt=2;
			}else if((x1==1 && y1!=1 && y1!=m) || (x2==1 && y2!=1 && y2!=m)) {
				cnt=3;
			}else if((y1==1 && x1!=1 && x1!=n) || (y2==1 && x2!=1 && x2!=n)) {
				cnt=3;
			}else if((x1==n && y1!=1 && y1!=m) || (x2==n && y2!=1 && y2!=m)) {
				cnt=3;
			}else if((y1==m && x1!=1 && x1!=n) || (y2==m && x2!=1 && x2!=n)) {
				cnt=3;
			}else if(x1!=1 && x2!=1 && y1!=1 && y2!=1) {
				cnt=4;
			}
			System.out.println(cnt);
			t--;
		}
		cin.close();
		return ;
	}
}

G.李華と模様

質問:長さ n の配列が与えられた場合、k 回の操作を実行して 2 次元配列を 180 度反転して、元の配列と同じ長さにすることができます。

解決策:まず、回転後の元の色と異なる cnt の数を見つけます。操作ごとに色 k-1 を変更できます。

k<cntの場合は明らかに長さが異なります。

k>=cnt、k が奇数の場合、次の 2 つのケースがあります。

1. n が奇数の場合、k は中点を変換できるため、対称になります。

2. nが偶数の場合は質問の意味を満たせないので、どう変えても違ってしまいます。

kが偶数であればどのように変えても問題の意味を満たします。

コード:

import java.util.Scanner;

public class G {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			t--;
			int n = cin.nextInt();
			int k = cin.nextInt();
			int [][]a = new int[1005][1005];
			for(int i=0; i<n; i++) {
				for(int j=0; j<n; j++) {
					int x = cin.nextInt();
					a[i][j] = x;
				}
			}
			int cnt=0;
			for(int i=0; i<n; i++) {
				for(int j=0; j<n; j++) {
//					System.out.println(a[i][j] + " " + a[n-i-1][n-j-1]);
					if(a[i][j] != a[n-i-1][n-j-1]) {
						cnt++;
					}
				}
			}
//			System.out.println(cnt);
			cnt /= 2;
			int flag=1;
			if(k>=cnt) {
				int ans = k-cnt;
				if(ans%2!=0 && n%2==0) { 
					flag=0;
				}
			}else {
				flag=0;
			}
			if(flag==0) {
				System.out.println("NO");
			}else {
				System.out.println("YES");
			}
//这样写会时间超限,不能有太多if/else
//			if(k>=cnt) {
//				int ans = k-cnt;
//				if(ans%2==0) { 
//					System.out.println("YES");
//				}else { 
//					if(n%2==0) {
//						System.out.println("NO");
//					}else {
//						System.out.println("YES");
//					}
//				}
//			}else {
//				System.out.println("NO");
//			}
		}
	}
}

I. ラッキーナンバー

タイトルの意味:

答え:

コード:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class I {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		int []g = new int[10];
		ArrayList<Integer> list = new ArrayList<>();
		list.add(-1);
		for(int i=1; i<=1000000; i++) {
			int k=0,r=i;
			while(r!=0) {
				g[k] = r%10;
				r/=10;
				k++;
			}
			int a=Integer.MIN_VALUE,b=Integer.MAX_VALUE;
			for(int j=0; j<k; j++) {
//				System.out.println(g[j]);
				a = Math.max(g[j], a);
				b = Math.min(g[j], b);
			}
//			System.out.println(a+" " + b);
			int c =  Math.abs(a-b);
			list.add(c);
		}
		while(t>0) {
			t--;
			int n = cin.nextInt();
			int m = cin.nextInt();
			int maxx = -1, sum=0;
			Map<Integer,Integer> mp = new HashMap<>();
			if(n<10 && m>=10) {
				n=10;
			}
			if((m-n)<100) {
				for(int i=n; i<=m; i++) {
					mp.put(list.get(i), i);
					maxx = Math.max(maxx,list.get(i));
				}
				System.out.println(mp.get(maxx));
			}else {
				int y = n%100; //最后两位
				int x = (n/100)%10; //倒数第三位
				int z = n/1000; //从第一个数字到倒数第四位
//				System.out.println(z + " " + x + " "+ y);
				if(y>9) {
					int jw = (x+1)/10;
					int p = z%10; //倒数第四位开始逐个往前缩进
					if(jw==0) { //不需要进位
						sum = (z*10+x+1)*100+9;
					}else { //需要进位
						sum += (x+1)%10*100+9;
						int bs = 1000;
						while(z>0) {
							p += jw;
							jw = p/10;
							x = p%10;
							sum += x*bs;
							bs *= 10; 
//							System.out.println(z + " " + sum + " " +jw);
							z /= 10;
							p = z%10;
						}
						if(z==0 && jw!=0) {
							sum += jw*bs;
						}
					}
				}else {
					sum = (z*10+x)*100+9;
				}
				
				System.out.println(sum);
			}
		}
	}
}

J. カジノで遊ぶ

質問の意図:長さ m の n 個の配列が与えられた場合、各グループが指定された式に従って並べ替えおよび結合後の結果の合計を取得します。

解決策:まず、ペアのペアのすべての結果を見つけてから、各式セットの順序に従って結果の合計を計算します。

コード:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Arrays;
import java.util.Collections;

public class J {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			t--;
			long n = cin.nextInt();
			long m = cin.nextInt();
			ArrayList<ArrayList<Long>> re = new ArrayList<>();		
			ArrayList<Integer> b = new ArrayList<>();
			ArrayList<Long> last = new ArrayList<>();
			for(int i=0; i<n; i++) {
				ArrayList<Long> row = new ArrayList<>();
				b.add(i);
				for(int j=0; j<m; j++) {
					long x = cin.nextInt();
					row.add(x);
				}
				re.add(row);
				
				if(i==0) {
					last.add(n-1);
				}else if(i>0 && i!=n-1) {
					long r = i+1;
					long now = last.get(i-1)-(r-1)+n-r;
//					System.out.println(now);
					last.add(now);
				}
			}
			ArrayList<ArrayList<Long>> fz = new ArrayList<>();
			long sum=0,cnt=0;
			for(int i=0; i<m; i++) {
				ArrayList<Long> lie = new ArrayList<>();
				for(int j=0; j<n; j++) {
//					System.out.print(re.get(j).get(i) + " ");
					lie.add(re.get(j).get(i));
				}
				Collections.sort(lie);
//				System.out.println(lie);
				fz.add(lie);
				for(int j=0; j<n-1; j++) {
					cnt = fz.get(i).get(j+1) - fz.get(i).get(j);
					sum += cnt * last.get(j);
				}
			}
			System.out.println(sum);
		}   
	}
}

拡大:

ArrayList を使用して動的 2 次元配列を作成します。

import java.util.ArrayList;
import java.util.List;

public class I {
	public static void main(String []args) {
		//创建一个二维数组
        List<List<Integer>> re = new ArrayList<List<Integer>>();
        //增加元素
        //添加行
        List<Integer> listRow = new ArrayList<>();
        listRow.add(1);
        listRow.add(3);
        listRow.add(5);
        listRow.add(7);
        listRow.add(9);
        //把行添加到二维数组
        re.add(listRow);

        //添加列
        List<Integer> listColumn = new ArrayList<>();
        listColumn.add(0);
        listColumn.add(2);
        listColumn.add(4);
        listColumn.add(6);
        listColumn.add(8);
        re.add(listColumn);
        System.out.println(re);
  
        for (int i = 0; i < re.size(); i++) {
            for (int j = 0; j < ((ArrayList) re.get(i)).size(); j++) {
                String str = ((ArrayList) re.get(i)).get(j).toString();
                System.out.print(str + " ");
            }
            System.out.println("");
        }
	}
}

出力:

注:動的な 2 次元配列に行を追加するには、異なる ArrayList が更新されるように、ループの最初の層で定義する必要があります。そうしないと、すべてが同じ行に追加されたように見えます。

正しくない:

正しい:

一連の数値のペアごとの組み合わせの結果をすべて検索します。

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Arrays;

public class J {
	public static void main(String []args) {
		List<Integer> mylist = Arrays.asList(1,2,3);
	     //Map<Integer, Integer> mymap = new HashMap<Integer, Integer>();
	     List<String> list = new ArrayList<String>();
	     for(int i=0;i< mylist.size()-1;i++)
	     {
	          for(int j=i+1;j< mylist.size();j++)
	          { 
	                list.add(mylist.get(i)+":"+mylist.get(j));   
	          }
	     }
	     for(int k = 0; k< list.size(); k++)
	     {
	          System.out.println(list.get(k));
	     }
	}
}

出力:

K. ショーストッパー

タイトルの意味:

答え:

コード:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class I {
	public static void main(String []args) {
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt();
		while(t>0) {
			t--;
			int n = cin.nextInt();
			int []a = new int[105];
			int []b = new int[105];
			for(int i=0; i<n; i++) {
				int x = cin.nextInt();
				a[i] = x;
			}
			for(int i=0; i<n; i++) {
				int x = cin.nextInt();
				b[i] = x;
			}
			int maxx = Math.max(a[n-1], b[n-1]);
			int flag=1;
			for(int i=0; i<n-1; i++) {
				if(maxx<a[i] || maxx<b[i]) {
					flag=0;
				}
			}
			if(maxx==a[n-1]) {
				for(int i=n-2; i>=0; i--) {
					if(b[i]>b[n-1] && a[i]>b[n-1]) {
						flag=0;
					}
				}
			}else if(maxx==b[n-1]){
				for(int i=n-2; i>=0; i--) {
					if(a[i]>a[n-1] && b[i]>a[n-1]) {
						flag=0;
					}
				}
			}
			if(flag==0) {
				System.out.println("No");
			}else {
				System.out.println("Yes");
			}
		}
	}
}

L. スリーセブンズ

タイトルの意味:

答え:

コード:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class L {
	public static void main(String []args) {
		Scanner scanner=new Scanner(System.in);
        int t=scanner.nextInt();
        while(t-->0) {
           int m=scanner.nextInt();
           HashMap<Integer,Integer> playerDay=new HashMap<>(5000);//key为玩家编号,value为天数
           for(int i=1;i<=m;i++){
               int n=scanner.nextInt();
               for(int j=1;j<=n;j++){
                   int x=scanner.nextInt();
                   playerDay.put(x,i);//存储玩家可能获奖的最近的那一天
               }
           }
           List<Integer>ans=new ArrayList<>();
           HashMap<Integer,Integer> dayPlayer=new HashMap<>(5000);//key为玩家编号,value为天数
            // 构建 value-key 映射
            for (Map.Entry<Integer, Integer> entry : playerDay.entrySet()) {
                dayPlayer.put(entry.getValue(), entry.getKey());
            }
           for(int i=1;i<=m;i++){//遍历每一天
               if(dayPlayer.get(i)!=null)ans.add(dayPlayer.get(i));
           }
           if(ans.size()<m) System.out.println(-1);
           else{
               for (int i = 0; i < m; i++) {
                   System.out.print(ans.get(i)+" ");
                   if(i==m-1) System.out.println();
               }
           }
        }
    }

}

M. キャンディストア

タイトルの意味:

答え:

コード:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=2e5+10;
ll a[N],b[N];
ll s[N];
int main()
{
    //cout<<2%3<<endl;
    ll t,n;
    cin>>t;
    int cnt=0;
    while(t--)
    {
        cnt++;
        cin>>n;
        for(int i=1; i<=n; i++)
        {
            cin>>a[i]>>b[i];
            s[i]=a[i]*b[i];
        }

        ll ans=n,x=0,g=s[1],l=b[1];
        for(int i=2; i<=n; i++)
        {
            g=__gcd(g,s[i]);
            ll tt=__gcd(l,b[i]);
            l=b[i]*l/tt;
            //cout<<g<<" "<<l<<endl;
            if(g%l==0){
                ans--;
            }else{
                g=s[i];
                l=b[i];
            }
        }
        cout<<ans<<'\n';
    }
}
//3213112

おすすめ

転載: blog.csdn.net/m0_62811051/article/details/130395041