模拟算法题目


找出游戏的获胜者 (约瑟夫环)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    //约瑟夫环问题-模拟
    int findTheWinner(int n, int k) {
        //编号:0~n-1
        if(n==1)return 1;
        if(k==1)return n;
        vector<bool>vis(n,false);
        int rest=n;//剩余rest人
        int i=0;
        int cnt=0;
        while(rest>1){
            if(!vis[i]){
                if(cnt+1==k){
                    cnt=0;
                    vis[i]=true;
                    --rest;
                }else{
                    ++cnt;
                }

            }

            i=i==n-1?0:i+1;//模拟环
        }
        for(int i=0;i<n;++i){
            if(!vis[i]){
                return i+1;
            }
        }
        return 0;//无意义的返回
    }
};

在这里插入图片描述


屏幕可显示句子的数量 (模拟+循环节)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    int wordsTyping(vector<string>& sentence, int rows, int cols) {
        int cnt=0;
        int rest=cols;
        int r=0;
        int index=0;
        bool is=false;
        int size=sentence.size();
        while(r<rows){
            int len=index==size?sentence[0].length():sentence[index].length();
            if(index==size){
                index=0;
                ++cnt;
                if(!is&&rest<sentence[0].length()){//判断是否出现循环节
                    ++r;
                    //循环节行数r
                    cnt*=(rows/r);
                    r=rows-rows%r;
                    rest=cols;
                    is=true;
                }
            }
            
            if(rest<=0||rest<len){
                rest=cols;
                ++r;
            }else{
                rest-=len+1;
                ++index;
            }
        }
        
        return cnt;
        
    }
};

在这里插入图片描述


旋转图像

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n=matrix.size();
        if(n==1)return;
        for(int r=0;r<(n>>1);++r){//进行r轮
            //每轮开始行row0=r,开始列col0=r;
            //每轮的len=(n>>r);
            int len=n-(r<<1);
            int row0=r,col0=r;
            int row1=r+len-1;
            int col1=r+len-1;
            for(int i=0;i<len-1;++i){//一次交换四条边的对应位置上的元素
                int tmp=matrix[row0][col0+i];
                matrix[row0][col0+i]=matrix[row1-i][col0];
                matrix[row1-i][col0]=matrix[row1][col1-i];
                matrix[row1][col1-i]=matrix[row0+i][col1];
                matrix[row0+i][col1]=tmp;
            }
        }

    }
};

在这里插入图片描述


分糖果 II

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    vector<int> distributeCandies(int candies, int num_people) {
        //1~n
        //n+1~2n
        //2n+1~
        int k=0;
        while(k*(1+k)/2<=candies){
            k++;
        }
        k--;
        int rest=candies-k*(1+k)/2;
        //
        int index=k%num_people;
        index=(index==0?num_people-1:index-1);
        vector<int>ans(num_people,0);
        int round=(k%num_people==0?k/num_people-1:k/num_people)+1;
        // cout<<round;
        for(int i=0;i<=index;++i){
            ans[i]=round*((round-1)*num_people+i+i+2)/2;
        }
        for(int i=index+1;i<num_people;++i){
            ans[i]=(round-1)*((round-2)*num_people+i+i+2)/2;
        }
        if(rest!=0){
            if(index!=num_people-1){
                ans[index+1]+=rest;
            }else{
                ans[0]+=rest;
            }
        }
        return ans;
    }
};

在这里插入图片描述



Excel 表列序号

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    int titleToNumber(string columnTitle) {
        int i=0;
        int ans=0;
        while(i<columnTitle.length()){
            int n=columnTitle[i]-'A'+1;
            ans=ans*26+n;
            ++i;
        }
        return ans;
    }
};

在这里插入图片描述


Excel表列名称

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    string convertToTitle(int columnNumber) {
        string ans;
        while(columnNumber>0){
            columnNumber--;
            ans+=(char)('A'+columnNumber%26);
            columnNumber/=26;
        }
        reverse(ans.begin(),ans.end());
        return ans;
    }

};

在这里插入图片描述


顺时针打印矩阵

在这里插入图片描述

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int>ans;
        if(matrix.size()==0)return ans;
        if(matrix[0].size()==1){
            for(int i=0;i<matrix.size();++i){
                ans.push_back(matrix[i][0]);
            }
            return ans;
        }
        int isVisited[matrix.size()][matrix[0].size()];
        memset(isVisited,0,sizeof(isVisited));
        for(int row=0;row<(matrix.size()>>1);++row){
            int len1=matrix[0].size()-row*2;
            int len2=matrix.size()-row*2;
            int r1=row;
            int c1=row;
            int r2=r1+len2-1;
            int c2=c1+len1-1;
            // cout<<r1+" "<<r2+" "<<c1+" "<<c2<<endl;
            for(int i=0;i<len1-1;++i){
                if(isVisited[r1][c1+i]==0){
                    ans.push_back(matrix[r1][c1+i]);
                    isVisited[r1][c1+i]=1;
                }else{
                    goto flag;
                }
                
            }
            // ans.push_back(-1);
            for(int i=0;i<len2-1;++i){
                if(isVisited[r1+i][c2]==0){
                    ans.push_back(matrix[r1+i][c2]);
                    isVisited[r1+i][c2]=1;
                }else{
                    goto flag;
                }
                
                
            }
            for(int i=0;i<len1-1;++i){
                if(isVisited[r2][c2-i]==0){
                    ans.push_back(matrix[r2][c2-i]);
                    isVisited[r2][c2-i]=1;
                }else{
                    goto flag;
                }
                
            }
            for(int i=0;i<len2-1;++i){
                if(isVisited[r2-i][c1]==0){
                    ans.push_back(matrix[r2-i][c1]);
                    isVisited[r2-i][c1]=1;
                }else{
                    goto flag;
                }
                
            }
            
        }
        if(matrix.size()%2==1){
            int len=matrix[0].size()-matrix.size()/2*2;
            for(int i=0;i<len;++i){
                if(isVisited[matrix.size()/2][matrix.size()/2+i]!=1){
                    ans.push_back(matrix[matrix.size()/2][matrix.size()/2+i]);
                    
                }
                    
            }
        }flag:
        return ans;
    }
};

在这里插入图片描述


圆形赛道上经过次数最多的扇区

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解题思路:

中间的循环对最终的结果没有影响,关键在于 开始位置结束位置

在这里插入图片描述

class Solution {
public:
    vector<int> mostVisited(int n, vector<int>& rounds) {
        vector<int>ans;
        int start=rounds.front();
        while(start!=rounds.back()){
            ans.push_back(start);
            start++;
            start=start>n?start%n:start;
        }
        ans.push_back(start);
        std::sort(ans.begin(),ans.end());
        return ans;
    }
};

在这里插入图片描述




字符串的左右移

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    string stringShift(string s, vector<vector<int>>& shift) {
        int left=0;
        int right=0;
        for(int i=0;i<shift.size();++i){
            if(shift[i][0]==0){
                left+=shift[i][1];
            }else{
                right+=shift[i][1];
            }
        }

        if(left==right)return s;
        else if(left>right){
            left-=right;
            left%=s.length();
            s=s.substr(left,s.length())+s.substr(0,left);
            return s;
        }
        right-=left;
        right%=s.length();
        s=s.substr(s.size()-right,s.length())+s.substr(0,s.length()-right);
        return s;
    }
};

在这里插入图片描述




可被 5 整除的二进制前缀

在这里插入图片描述
在这里插入图片描述

思路:

此题如果老老实实算出二进制数,很明显会 溢出
可被5整除的数字只跟该数字的最后一位数字(为0或5)有关系,于是不需要具体的算出二进制前缀对应的十进制整数是多少,只需 每次保留最后一位数字(保留用该数字对10取余的十进制整数的结果)就好,而下一个二进制前缀对应的十进制整数 = 上一次的结果左移一位(乘以2)的结果 + 这次的A[i](0或者1,正好对应十进制的0或者1)的结果。

class Solution {
public:
    vector<bool> prefixesDivBy5(vector<int>& nums) {
        int value=0;
        vector<bool>ans;
        for(int i=0;i<nums.size();++i){
            value=(value<<1)+nums[i];
            value%=10;
            if(value==0||value==5){
                ans.push_back(true);
            }else{
                ans.push_back(false);
            }
        }
        return ans;
    }
};

在这里插入图片描述




找出井字棋的获胜者


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean isWin(int[][] moves,List<Integer>list){
        if(list.size()<3)return false;
        for(int i=0;i<list.size();++i){
            for(int j=0;j<list.size();++j){
                if(j==i)continue;
                for(int k=0;k<list.size();++k){
                    if(k==i||k==j)continue;
                    int ii=list.get(i);
                    int jj=list.get(j);
                    int kk=list.get(k);
                    if(moves[ii][0]==moves[jj][0]&&moves[kk][0]==moves[jj][0])return true;
                    if(moves[ii][1]==moves[jj][1]&&moves[kk][1]==moves[jj][1])return true;
                    if(moves[ii][0]*2==moves[jj][0]+moves[kk][0]&&moves[ii][1]*2==moves[jj][1]+moves[kk][1])return true;
                    if(moves[jj][0]*2==moves[ii][0]+moves[kk][0]&&moves[jj][1]*2==moves[ii][1]+moves[kk][1])return true;
                    if(moves[kk][0]*2==moves[jj][0]+moves[ii][0]&&moves[kk][1]*2==moves[jj][1]+moves[ii][1])return true;
                }
            }
        }
        return false;
    }
    public String tictactoe(int[][] moves) {
        if(moves.length<5)return "Pending";
        
        List<Integer>A=new ArrayList<>();
        List<Integer>B=new ArrayList<>();
        for(int i=0;i<moves.length;++i){
            if((i&1)==0){
                A.add(i);
            }else{
                B.add(i);
            }
        }
        if(isWin(moves,A))return "A";
        if(isWin(moves,B))return "B";
        if(moves.length==9)return "Draw";
        return "Pending";
    }
}

在这里插入图片描述



圆圈中最后剩下的数字 (约瑟夫环)


在这里插入图片描述

class Solution {
    
    public int lastRemaining(int n, int m) {
        if(n==1)return 0;
        if(m==1)return n-1;
        List<Integer>list=new ArrayList<>();
        for(int i=0;i<n;++i){
            list.add(i);
        }
        int i=0;
        while(list.size()>1){
            i=(i+m-1)%(list.size());
            list.remove(i);
            
        }
        return list.get(0);

    }
}

在这里插入图片描述



旋转词

在这里插入图片描述

在这里插入图片描述

题目解析: KMP算法应用


import java.util.Scanner;

//模拟-旋转词
public class Main {
	public static class KMP{
		public String s1;
		public String s2;//目标串
		public int next[];
		public KMP(String s1,String s2) {
			this.s1=s1;
			this.s2=s2;
			if(s2.length()>0)next=new int[s2.length()];
		}
		public void getNextArray() {
			if(s2.length()==1) {
				next[0]=-1;
				return;
			}
			next[0]=-1;
			next[1]=0;
			int i=2;
			int cn=0;//从0开始与s2[i-1]比对
			while(i<s2.length()) {
				if(s2.charAt(next[i-1])==s2.charAt(cn)) {
					next[i++]=++cn;
				}else if(cn>0) {
					cn=next[cn];
				}else {//cn<=0
					++i;
				}
			}
		}
		public int getIndexOf() {
			if(s2.length()>s1.length()) {
				return -1;
			}
			getNextArray();
			int x=0;
			int y=0;
			while(x<s1.length()&&y<s2.length()) {
				if(s1.charAt(x)==s2.charAt(y)) {
					x++;
					y++;
				}
				else if(next[y]==-1) {
					x++;
				}else {
					y=next[y];
				}
			}
			return y==s2.length()?x-y:-1;
		}
	}
	public static boolean isRotateWord(String s1,String s2) {
		if(s1.length()!=s2.length())return false;
		s1+=s1;
		//KMP判断s2是否是s1的字串
		KMP kmp=new KMP(s1,s2);
		return kmp.getIndexOf()!=-1?true:false;
		
		
	}
	public static void main(String[] args) {
		Scanner scan=new Scanner(System.in);
		int n,m;
		n=scan.nextInt();
		m=scan.nextInt();
		scan.nextLine();
		String s1,s2;
		s1=scan.nextLine();
		s2=scan.nextLine();
		boolean ans=isRotateWord(s1,s2);
		if(ans)System.out.println("YES");
		else System.out.println("NO");
		
	}

}

在这里插入图片描述



旋转矩阵

在这里插入图片描述

import java.util.*;

public class Solution {
    public void process(int[][] mat,int a,int b,int c,int d){
        for(int i=0;i<d-b;++i){
            int tmp=mat[c-i][b];
            mat[c-i][b]=mat[c][d-i];
            mat[c][d-i]=mat[a+i][d];
            mat[a+i][d]=mat[a][b+i];
            mat[a][b+i]=tmp;
        }
    }
    public int[][] rotateMatrix(int[][] mat, int n) {
        // write code here
        int a=0;
        int b=0;
        int c=n-1;
        int d=n-1;
        while(b<d){
            process(mat,a++,b++,c--,d--);
        }
        return mat;
    }
}

在这里插入图片描述



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值