• 个人简介


    (~ ̄▽ ̄)~ 一枚蒟蒻的主页

    你是我主页第位访客

    (点击三角形打开文件夹)

    有趣的代码
    代码模板
    图论
    1. Dijkstra (正权图)
    #include <iostream>
    #include <vector>
    #include <queue>
    #include <cstring>
    using namespace std;
    struct node
    {
    	int v,w;
    	bool operator<(const node a)const{return w>a.w;}
    };
    int n,m,u,v,w,d[10001],vis[10001];
    vector<node> g[10001];
    priority_queue<node> pq;
    void dijkstra(int x) 
    {
    
        memset(vis,false,sizeof vis);
        memset(d,127,sizeof d);
    	d[x]=0;
    	pq.push((node){x,0});
    	while(!pq.empty())
        {
    		int u=pq.top().v;
    		pq.pop();
            if(vis[u]) continue;
            vis[u]=true;
            for(int i=0;i<g[u].size();i++) 
    		{
    			int v=g[u][i].v;
    			int w=g[u][i].w;
    			if(d[u]+w<d[v]) 
    			{
    				d[v]=d[u]+w;
    				pq.push((node){v,d[v]});
    			}
    		}
    	}
    }
    int main() 
    {
    	cin>>n>>m;
    	for(int i=1;i<=m;i++) 
    	{
    		cin>>u>>v>>w;
    		g[u].push_back((node){v,w});
    		//g[v].push_back((node){u,w});
    	}
    	dijkstra(1);
    	if(d[n]==d[0]) cout<<"No path is reachable";
        else cout<<d[n];
      return 0;
    }
    
    1. SPFA(关于 SPFA ,它已经死了)
    #include<bits/stdc++.h>
    using namespace std;
    struct edge{int v,w;};
    int n,m,u,v,w,d[10001];
    vector<edge> g[10001];
    bool vis[10001];
    queue<int> q;
    void spfa(int u)
    {
        memset(d,127,sizeof(d));
        d[u]=0,vis[u]=true;
        q.push(u);
        while(!q.empty())
    	{
            int u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=0;i<g[u].size();i++)
    		{
            	int v=g[u][i].v;
                int w=g[u][i].w;
                if(d[u]+w<d[v])
    			{
                    d[v]=d[u]+w;
                    if(!vis[v])
    				{
                        q.push(v);
                        vis[v]=true;
                    }
                }
            }
        }
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
    	{
            cin>>u>>v>>w;
            g[u].push_back({v,w});
        }
        spfa(1);
        if(d[n]==d[0]) cout<<"No path is reachable";
        else cout<<d[n];
        return 0;
    }
    
    1. Floyd (小数据)
    #include<bits/stdc++.h>
    using namespace std;
    const int INF=1e9;
    int n,m,q,u,v,w;
    int f[305][305];
    void floyd()
    {
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
    				f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    }
    int main()
    {
    
    	cin>>n>>m>>k;
    	for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i==j) f[i][j]=0;
                else f[i][j]=INF;
        for(int i=1;i<=m;i++)
        {
    		cin>>u>>v>>w;
    		f[u][v]=min(f[u][v],w);
    	}
    	floyd();
    	while(q--)
        {
    		cin>>u>>v;
    		if(f[u][v]>INF/2) cout<<"No path is reachable";
        	else cout<<f[u][v]<<endl;
    	}
        return 0;
    }
    
    
    排序算法模版

    豆老师生成,来不及整理了

    // 插入排序:优化版本(赋值代替交换,提前终止)
    void insertionSort(vector<int>& arr) 
    {
        int n=arr.size();
        for(int i=1;i<n;i++) 
    	{
            int key=arr[i],j=i-1; // key 为当前待插入元素
            // 跳过已有序的元素,找到插入位置(提前终止)
            while(j>=0&&arr[j]>key) arr[j+1]=arr[j],--j;// 赋值代替交换(减少一次操作)
            arr[j+1]=key; // 插入到正确位置
        }
    }
    
    // 选择排序:优化版本(同时找最大/最小值,减少遍历次数)
    void selectionSort(vector<int>& arr) 
    {
        int n=arr.size();
        int left=0,right=n-1;
    	while(left<right) 
    	{
            int minIdx=left; // 最小值索引
            int maxIdx=right; // 最大值索引
    		// 一次遍历同时找当前区间的最小/最大值
            for(int i=left;i<=right;i++) 
    		{
                if(arr[i]<arr[minIdx]) minIdx=i;
                if(arr[i]>arr[maxIdx]) maxIdx=i;
            }  
    		// 交换最小值到左端点
            swap(arr[left],arr[minIdx]);  // 若最大值在左端点(被交换过),更新 maxIdx
            if (maxIdx==left) maxIdx=minIdx;  // 交换最大值到右端点
            swap(arr[right],arr[maxIdx]);
    		++left,--right;
        }
    }
    
    // 冒泡排序:优化版本(记录最后交换位置,减少无效循环)
    void bubbleSort(vector<int>& arr)
    {
        int n=arr.size();
        int lastSwap=n-1; // 记录最后一次交换的位置
    	while(lastSwap>0) 
    	{
            int temp=0; // 临时记录本次交换的位置
            for(int i=0;i<lastSwap;i++) 
    			if(arr[i]>arr[i+1]) 
    				swap(arr[i],arr[i+1]),temp=i; // 更新本次交换的位置
            lastSwap=temp; // 下次只遍历到本次最后交换的位置(后续已有序)
        }
    }
    
    // 希尔排序:优化版本(Hibbard 步长序列)
    void shellSort(vector<int>& arr) 
    {
        int n=arr.size();
        int gap=1;
    	// 生成 Hibbard 步长序列:1, 3, 7, ..., 2^k - 1(小于 n/3)
        while(gap<n/3) gap=gap*3+1;
        // 按步长递减进行插入排序
        while(gap>0) 
    	{
            for(int i=gap;i<n;i++) 
    		{
                int key=arr[i];
                int j=i-gap;
                // 步长为 gap 的插入排序
                while(j>=0&&arr[j]>key) arr[j+gap]=arr[j],j-=gap;
                arr[j+gap]=key;
            }
            gap/=3; // 步长递减(Hibbard 序列的逆过程)
        }
    }
    
    // 堆调整:迭代实现下沉法(最大堆)
    void heapify(vector<int>& arr,int n,int i) 
    {
        while(true) 
    	{
            int largest=i,left=2*i+1,right=2*i+2;  //当前,左,右节点
    		// 找到当前节点、左子节点、右子节点中的最大值
            if(left<n&&arr[left]>arr[largest]) largest=left;
            if(right<n&&arr[right]>arr[largest]) largest=right;
    		// 若最大值不是当前节点,交换并继续下沉
            if(largest!=i) 
                swap(arr[i],arr[largest]),i=largest; // 下沉到子节点
            else break; // 已满足最大堆性质,退出
        }
    }
    // 堆排序:优化版本(迭代堆调整,原地排序)
    void heapSort(vector<int>& arr) 
    {
        int n=arr.size();
    	// 1. 构建最大堆(从最后一个非叶子节点开始下沉)
        for(int i=n/2-1;i>=0;i--) heapify(arr,n,i);
        // 2. 堆排序:逐个提取堆顶元素(最大值)
        for(int i=n-1;i>0;i--) 
            swap(arr[0],arr[i]),heapify(arr,i,0);  // 堆顶(最大值)交换到数组末尾  // 对剩余元素重新构建最大堆(仅需调整堆顶)
    }
    
    // 插入排序:用于归并排序的小规模子数组优化
    void insertionSort(vector<int>& arr,int left,int right) 
    {
        for(int i=left+1;i<=right;i++) 
    	{
            int key=arr[i],j=i-1;
            while(j>=left&&arr[j]>key) arr[j+1]=arr[j],--j;
            arr[j+1]=key;
        }
    }
    // 合并两个有序子数组:arr[left..mid] 和 arr[mid+1..right]
    void merge(vector<int>& arr,vector<int>& temp,int left,int mid,int right)
    {
        // 拷贝到临时数组
        copy(arr.begin()+left,arr.begin()+right+1,temp.begin()+left);
    	int i=left,j=mid+1,k=left;  // 左,右子数组指针,合并后数组指针
        // 合并两个子数组(稳定排序:相同元素左子数组优先)
        while(i<=mid&&j<=right) 
    	{
            if (temp[i]<=temp[j]) arr[k++]=temp[i++];
            else arr[k++]=temp[j++];
        }
    	// 拷贝左子数组剩余元素(右子数组剩余元素已在原位置)
        while(i<=mid) arr[k++]=temp[i++];
        
    }
    // 归并排序:优化版本(自底向上迭代,小规模子数组用插入排序)
    void mergeSort(vector<int>& arr) 
    {
        int n=arr.size();
        if(n<=1) return;
        vector<int> temp(n); // 临时数组(仅分配一次,减少开销)
        const int INSERTION_SORT_THRESHOLD=16; // 小规模子数组阈值
    	// 自底向上:按子数组长度迭代合并(长度从 1 开始,每次翻倍)
        for(int len=1;len<n;len*=2) 
    	{
            for(int left=0;left<n;left+=2*len)
    		{
                int mid=left+len-1; // 左子数组末尾
                int right=min(left+2*len-1,n-1); // 右子数组末尾(避免越界)
    			// 优化:小规模子数组改用插入排序
                if(len<=INSERTION_SORT_THRESHOLD) insertionSort(arr,left,right);
                else merge(arr,temp,left,mid,right);
            }
        }
    }
    
    // 插入排序:用于快速排序的小规模子数组优化
    void insertionSort(vector<int>& arr,int left,int right) 
    {
        for(int i=left+1;i<=right;i++)
    	{
            int key=arr[i],j=i-1;
            while (j>=left&&arr[j]>key) arr[j+1]=arr[j],--j;
            arr[j+1]=key;
        }
    }
    // 三数取中法:选择 pivot(避免最坏情况)
    int medianOfThree(vector<int>& arr,int left,int right) 
    {
        int mid=left+(right-left)>>1;
        // 排序 left、mid、right 三个位置,取 mid 作为 pivot
        if(arr[left]>arr[mid]) swap(arr[left],arr[mid]);
        if(arr[left]>arr[right]) swap(arr[left],arr[right]);
        if(arr[mid]>arr[right]) swap(arr[mid],arr[right]);
        swap(arr[mid],arr[right-1]); // 将 pivot 放到 right-1 位置(方便后续分区)
        return arr[right-1];
    }
    // 快速排序分区(三路快排:处理重复元素优化)
    void partition(vector<int>& arr,int left,int right,int& lt,int& gt)
    {
        int pivot=medianOfThree(arr,left,right); // 三数取中法选 pivot
        lt=left;
        gt=right;
        int i=left;
    	while(i<=gt) 
    	{
            if (arr[i]<pivot) swap(arr[lt++],arr[i++]);
            else if(arr[i]>pivot) swap(arr[i],arr[gt--]);
            else i++; // 相等元素跳过,集中在 lt~gt 区间
        }
    }
    // 快速排序:优化版本(三数取中、三路快排、小规模插入排序、尾递归优化)
    void quickSort(vector<int>& arr,int left,int right)
    {
        const int INSERTION_SORT_THRESHOLD=16; // 小规模子数组阈值
    	while(left<right) 
    	{
            // 优化:小规模子数组改用插入排序
            if(right-left+1<=INSERTION_SORT_THRESHOLD) 
    		{
    			insertionSort(arr,left,right); 
    			return;
    		}
            int lt,gt;
            partition(arr,left,right,lt,gt); // 三路分区
    		// 尾递归优化:先处理较小的子数组,减少递归栈深度
            if(lt-left<right-gt) quickSort(arr,left,lt-1),left=gt+1; // 较大的子数组用循环处理(尾递归优化)
            else quickSort(arr,gt+1,right),right=lt-1; // 较大的子数组用循环处理(尾递归优化)
        }
    }
    // 快速排序对外接口
    void quickSort(vector<int>& arr) 
    {
        if(arr.empty()) return;
        quickSort(arr,0,arr.size()-1);
    }
    
    // 计数排序:优化版本(动态范围、前缀和、稳定性)
    void countingSort(vector<int>& arr) 
    {
        if(arr.empty()) return;
    	// 1. 动态计算数据范围(min 和 max),节省空间
        int minVal=*min_element(arr.begin(),arr.end());
        int maxVal=*max_element(arr.begin(),arr.end());
        int range=maxVal-minVal+1;
    	// 2. 计数数组(统计每个元素出现次数)
        vector<int> count(range,0);
        for(int num:arr) ++count[num-minVal]; // 偏移量:将 minVal 映射到 0
        // 3. 前缀和:计算每个元素的最终位置(稳定排序关键)
        partial_sum(count.begin(),count.end(),count.begin());
    	// 4. 从后往前遍历原数组,构建输出数组(保证稳定性)
        vector<int> output(arr.size());
        for(auto it=arr.rbegin();it!=arr.rend(); it++) 
    	{
            int num=*it;
            int pos=count[num-minVal]-1; // 最终位置(前缀和减 1)
            output[pos]=num;
            count[num-minVal]--; // 更新计数(下一个相同元素位置前移)
        }
    	// 5. 拷贝回原数组
        arr=output;
    }
    
    // 桶排序:优化版本(动态桶数量、插入排序、支持负数)
    void bucketSort(vector<int>& arr) 
    {
        if(arr.empty()) return;
    	// 1. 计算数据范围(支持负数)
        int minVal=*min_element(arr.begin(),arr.end());
        int maxVal=*max_element(arr.begin(),arr.end());
        int range=maxVal-minVal+1;
    	// 2. 动态确定桶的数量(通常设为 n 或 sqrt(n),这里用 n 平衡效率)
        int n=arr.size(),bucketCount=n;
    	// 3. 初始化桶(每个桶是一个 vector)
        vector<vector<int>> buckets(bucketCount);
    	// 4. 将元素分配到桶中(偏移量处理负数)
        for(int num:arr) 
    	{
            // 计算桶索引:(num - minVal) * (bucketCount - 1) / range(均匀分布)
            int bucketIdx=(num-minVal)*(bucketCount-1)/range;
            buckets[bucketIdx].push_back(num);
        }
    	// 5. 桶内排序(用插入排序保证稳定性,且对小规模数据高效)
        for(auto& bucket:buckets) 
    	{
            // 桶内插入排序(优化:小规模数据无需调用 std::sort)
            for(int i=1;i<bucket.size();i++) 
    		{
                int key=bucket[i];
                int j=i-1;
                while(j>=0&&bucket[j]>key) bucket[j+1]=bucket[j],--j;
                bucket[j+1]=key;
            }
        }
    	// 6. 合并所有桶到原数组
        int idx=0;
        for(const auto& bucket:buckets) 
    		for(int num:bucket) 
    		arr[idx++]=num;
    }
    
    // 基数排序的子排序:按指定位(个位、十位、百位...)进行计数排序(稳定)
    void radixCountingSort(vector<int>& arr,int exp,int minVal) 
    {
        int n=arr.size();
        vector<int> output(n);
        vector<int> count(10,0); // 基数为 10(0-9)
    	// 1. 统计每个位上的数字出现次数
        for(int num:arr) 
    	{
            // 计算当前位的数字(处理负数:num - minVal 转为非负数)
            int digit=((num-minVal)/exp)%10;
            count[digit]++;
        }
    	// 2. 前缀和:计算每个数字的最终位置
        for(int i=1;i<10;i++) count[i]+=count[i-1];
        // 3. 从后往前遍历,构建输出数组(保证稳定性)
        for(int i=n-1;i>=0;i--) 
    	{
            int num=arr[i];
            int digit=((num-minVal)/exp)%10;
            int pos=count[digit]-1;
            output[pos]=num;
            count[digit]--;
        }
    	// 4. 拷贝回原数组
        arr=output;
    }
    // 基数排序:优化版本(动态位数、支持负数、计数排序子排序)
    void radixSort(vector<int>& arr) 
    {
        if(arr.empty()) return;
    	// 1. 处理负数:计算最小元素,作为偏移量(将负数转为非负数)
        int minVal=*min_element(arr.begin(),arr.end());
        int maxVal=*max_element(arr.begin(),arr.end());
        // 计算最大数字的位数(处理偏移后的非负数)
        int maxNonNeg=maxVal-minVal;
        int d=0; // 位数
        do{++d,maxNonNeg/=10;}while(maxNonNeg>0);
    	// 2. 按位排序(从个位到最高位)
        int exp=1; // 10^0=1(个位),10^1=10(十位),...
        for(int i=0;i<d;i++) 
            radixCountingSort(arr,exp,minVal),exp*=10;
    }
    
    // 锦标赛排序:优化版本(迭代构建比赛树,稳定排序)
    void tournamentSort(vector<int>& arr) 
    {
        int n=arr.size();
        if(n<=1) return;
    	// 1. 构建比赛树(完全二叉树,大小为 2^ceil(log2(n)) * 2 - 1,简化为 2*n)
        int treeSize=2*n;
        vector<int> tree(treeSize,INT_MAX); // 比赛树(叶子节点存储元素,非叶子存储获胜者索引)
        vector<int> indices(treeSize); // 存储元素索引(用于稳定排序)
    	// 初始化叶子节点(从 n 开始,前 n 个叶子节点对应原数组)
        for(int i=0;i<n;i++) tree[n+i]=arr[i],indices[n+i]=i; // 记录原索引(保证稳定性)
        // 2. 构建比赛树(从最后一个非叶子节点向上计算获胜者)
        for(int i=n-1;i>0;i--) 
    	{
            int left=tree[2*i];
            int right=tree[2*i+1];
            int leftIdx=indices[2*i];
            int rightIdx=indices[2*i+1];
    		// 选择获胜者(值小的优先;值相等时,原索引小的优先,保证稳定性)
            if(left<right||(left==right&&leftIdx<rightIdx)) 
    			tree[i]=left,indices[i]=leftIdx;
            else tree[i]=right,indices[i]=rightIdx;
        }
    	// 3. 提取排序结果(每次提取根节点的获胜者,然后更新比赛树)
        vector<int> output(n);
        for(int i=0;i<n;i++) 
    	{
            output[i]=tree[1]; // 根节点是当前最小值
            int winnerIdx=indices[1]; // 获胜者的原索引
    		// 更新比赛树:将获胜者的叶子节点设为 INT_MAX(表示已被提取)
            int leafIdx=n+winnerIdx;
            tree[leafIdx]=INT_MAX;
            indices[leafIdx]=INT_MAX;
    		// 从叶子节点向上更新比赛树
            leafIdx/=2;
            while(leafIdx>0) 
    		{
                int left=tree[2*leafIdx];
                int right=tree[2*leafIdx+1];
                int leftIdx=indices[2*leafIdx];
                int rightIdx=indices[2*leafIdx+1];
    			// 重新计算获胜者
                if(left<right||(left==right&&leftIdx<rightIdx))
                    tree[leafIdx]=left,indices[leafIdx]=leftIdx;
                else tree[leafIdx]=right,indices[leafIdx]=rightIdx;
                leafIdx/=2;
            }
        }
    	// 4. 拷贝回原数组
        arr=output;
    }
    
    // 插入排序:用于扩展短 run
    void insertionSort(vector<int>& arr,int left,int right) 
    {
    	for(int i=left+1;i<=right;i++)
    	{
    		int key=arr[i],j=i-1;
    		while(j>=left&&arr[j]>key) arr[j+1]=arr[j],--j;
    		arr[j+1]=key;
    	}
    }
    // 合并两个有序 run:arr[left..mid] 和 arr[mid+1..right],返回合并后的长度
    int merge(vector<int>& arr,vector<int>& temp,int left,int mid,int right) 
    {
    	int len1=mid-left+1;
    	int len2=right-mid;
    	copy(arr.begin()+left,arr.begin()+mid+1,temp.begin());
    	copy(arr.begin()+mid+1,arr.begin()+right+1,temp.begin()+len1);
    	int i=0,j=0,k=left;
    	// 合并(稳定排序)
    	while(i<len1&&j<len2) 
    	{
    		if(temp[i]<=temp[j])
    			arr[k++]=temp[i++];
    		else arr[k++]=temp[j++];
    	}
    	// 拷贝剩余元素
    	while(i<len1) arr[k++]=temp[i++];
    	while(j<len2) arr[k++]=temp[j++];
    	return right-left+1;
    }
    // 计算 minRun(Tim 排序的核心参数,控制 run 的最小长度)
    int computeMinRun(int n) 
    {
    	int r=0;
    	while(n>=64) r|=n&1,n>>=1;
    	return n+r;
    }
    // Tim 排序:优化版本(利用自然有序段,归并合并,galloping 模式)
    void timSort(vector<int>& arr) 
    {
    	int n=arr.size();
    	if(n<=1) return;
    	// 1. 计算 minRun(最小 run 长度,通常为 32-64)
    	int minRun=computeMinRun(n);
    	vector<int> temp(n); // 临时数组
    	// 2. 遍历数组,划分 run 并排序短 run
    	vector<pair<int,int>> runStack; // 存储 run 的起始位置和长度(栈底到栈顶:run1, run2, ...)
    	int i=0;
    	while(i<n) 
    	{
    		// 2.1 找到当前 run 的起始位置和方向(递增或递减)
    		int start=i;
    		if(i+1<n&&arr[i]>arr[i+1]) 
    		{
    			// 递减 run,反转为递增
    			while(i+1<n&&arr[i]>arr[i+1]) i++;
    			reverse(arr.begin()+start,arr.begin()+i+1);
    		} 
    		else while(i+1<n&&arr[i]<=arr[i+1]) i++;
    		int runLen=i-start+1;
    		// 2.2 短 run 用插入排序扩展为 minRun 长度
    		if(runLen<minRun) 
    		{
    			int end=min(start+minRun-1,n-1);
    			insertionSort(arr,start,end);
    			runLen=end-start+1,i=end;
    		}
    		// 2.3 将 run 压入栈,并控制合并顺序(避免不平衡合并)
    		runStack.emplace_back(start,runLen);
    		while(runStack.size()>=2) {
    			int a=runStack[runStack.size()-2].second;
    			int b=runStack[runStack.size()-1].second;
    			// 合并规则:若 a > b + c 或 b > c(c 为前一个 run 的长度,若存在),则合并
    			if(runStack.size()>=3) 
    			{
    				int c=runStack[runStack.size()-3].second;
    				if(a<=b+c&&b<=c) break;
    			} 
    			else if(a<=b) break;
    			// 合并前两个 run
    			auto [start1,len1]=runStack[runStack.size()-2];
    			auto [start2, len2]=runStack[runStack.size()-1];
    			int mid=start1+len1-1;
    			int end=start2+len2-1;
    			merge(arr,temp,start1,mid,end);
    			// 更新栈:弹出两个 run,压入合并后的 run
    			runStack.pop_back();
    			runStack.pop_back();
    			runStack.emplace_back(start1,len1+len2);
    		}
    		i++;
    	}
    	// 3. 合并栈中剩余的所有 run
    	while(runStack.size()>1) 
    	{
    		auto [start1,len1]=runStack[runStack.size()-2];
    		auto [start2,len2]=runStack[runStack.size()-1];
    		int mid=start1+len1-1;
    		int end=start2+len2-1;
    		merge(arr,temp,start1,mid,end);
    		runStack.pop_back();
    		runStack.pop_back();
    		runStack.emplace_back(start1,len1+len2);
    	}
    }
    vector<int> a;
    int x;
    int main()
    {
    	while(cin>>x) a.push_back(x);
    	timSort(a);
    	for(int i:a) cout<<i<<" ";
    	return 0;
    }
    
    算法名称 平均时间复杂度 最坏时间复杂度 最好时间复杂度 空间复杂度 稳定性
    插入排序 O(n2)O(n^2) O(n2)O(n^2) O(n)O(n) O(1)O(1) 稳定
    选择排序 O(n2)O(n^2) 不稳定
    冒泡排序 O(n)O(n) 稳定
    希尔排序 O(nlogn)O(n \log n) 不稳定
    堆排序 O(nlogn)O(n \log n) O(nlogn)O(n \log n)
    归并排序 O(n)O(n) 稳定
    快速排序 O(n2)O(n^2) O(logn)O(\log n) 不稳定
    计数排序 O(n+k)O(n + k) O(n+k)O(n + k) O(k)O(k) 稳定
    桶排序 O(n2)O(n^2) O(n)O(n) O(n+k)O(n + k)
    基数排序 O(d(n+k))O(d(n + k))
    锦标赛排序 O(nlogn)O(n \log n) O(nlogn)O(n \log n) O(n)O(n)
    Tim 排序 O(n)O(n)

    并查集

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,t;
    vector<int> fa,size_v;
    int find(int x)
    {
    	if(fa[x]==x) return x;
    	return fa[x]=find(fa[x]);
    }
    void unite(int x,int y)
    {
    	x=find(x),y=find(y);
    	if(x==y) return ;
    	if(size_v[x]<size_v[y]) swap(x,y);
    	fa[y]=x;
    	size_v[x]+=size_v[y];
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(nullptr);
    	cout.tie(nullptr);
    	cin>>n>>m>>t;
    	fa.resize(n+1),size_v.resize(n+1);
    	for(int i=1;i<=n;i++) fa[i]=i;
    	for(int i=1,x,y;i<=m;i++)
    		cin>>x>>y,unite(x,y);
    	for(int i=1,x,y;i<=t;i++)
    	{
    		cin>>x>>y;
    		if(find(x)==find(y)) cout<<"Yes"<<endl;
    		else cout<<"No"<<endl;
    	}
    	return 0;
    }
    

    快速幂

    // a 的 u 次方模 mod
    int quickPow(int a,int u,int mod) 
    {
    	int res=1;  
    	a%=mod;     
    	while(u>0) 
    	{
    		if(u&1) res=(long long)res*a%mod; 
    		a=(long long)a*a%mod;  
    		u>>=1;
    	}
    	return res;
    }
    

    millerRabin(快判素数)

    #include<bits/stdc++.h>
    using namespace std;
    int test_time=10;
    // a 的 u 次方模 mod
    int quickPow(int a,int u,int mod) 
    {
    	int res=1;  
    	a%=mod;     
    	while(u>0) 
    	{
    		if(u&1) res=(long long)res*a%mod; 
    		a=(long long)a*a%mod;  
    		u>>=1;
    	}
    	return res;
    }
    bool millerRabin(int n) {
    	if(n<3||n%2==0) return n==2;
    	if(n%3==0) return n==3;
    	int u=n-1,t=0;
    	while(u%2==0) u/=2,++t;
    	// test_time 为测试次数,建议设为不小于 8
    	// 的整数以保证正确率,但也不宜过大,否则会影响效率
    	for(int i=0;i<test_time;i++) 
    	{
    		int a=rand()%(n-3)+2,v=quickPow(a,u,n);
    		if(v==1) continue;
    		int s;
    		for(s=0;s<t;s++) 
    		{
    			if(v==n-1) break;  
    			v=(long long)v*v%n;
    		}
    		if(s==t) return 0;
    	}
    	return 1;
    }
    int t,n;
    int main()
    {
    	cin>>t;
    	while(t--)
    	{
    		cin>>n;
    		if(millerRabin(n)) cout<<"YES";  //是否素数
    		else cout<<"NO";
    		puts("");
    	}
    	return 0;
    }
    

    差分

    #include<bits/stdc++.h> 
    using namespace std;
    int n,m;
    int q[200001],s[200001];
    void insert(int l,int r,int c){s[l]+=c,s[r+1]-=c;}
    int main()
    {
    	cin>>n>>m;
    	for(int i=1;i<=n;i++) cin>>q[i],insert(i,i,q[i]);
    	for(int i=1,l,r,c;i<=m;i++){cin>>l>>r>>c; insert(l,r,c);}
    	for(int i=1;i<=n;i++) s[i]+=s[i-1],cout<<s[i]<<" ";
    	return 0;
    }
    

    还没更新太多(~ ̄▽ ̄)~

    FX 的代码

    1. note.ms 占领器

    特别鸣谢: 某帖。。。

    #include <windows.h>
    #include <iostream>
    #include <stack>
    #include <tlhelp32.h>
    #include <string>
    #include <cstring>
    using namespace std;
    
    BYTE originalKeyState[256];
    void saveOriginalKeyStates() { GetKeyboardState(originalKeyState); }
    void restoreOriginalKeyStates() { SetKeyboardState(originalKeyState); }
    
    void presskey(WORD modifierKey, WORD targetKey) {
      keybd_event(modifierKey, 0, 0, 0);
      Sleep(10);
      keybd_event(targetKey, 0, 0, 0);
      Sleep(10);
      keybd_event(targetKey, 0, KEYEVENTF_KEYUP, 0);
      Sleep(10);
      keybd_event(modifierKey, 0, KEYEVENTF_KEYUP, 0);
      Sleep(10);
    }
    
    // 通过窗口标题查找并关闭窗口
    bool closeWindowByTitle(const char* titlePart) {
      HWND hwnd = FindWindowA(NULL, NULL);
      bool found = false;
      
      while (hwnd != NULL) {
          char windowTitle[256];
          GetWindowTextA(hwnd, windowTitle, sizeof(windowTitle));
          
          // 查找标题中包含指定内容的窗口
          if (strstr(windowTitle, titlePart) != NULL) {
              // 先尝试正常关闭
              SendMessageA(hwnd, WM_CLOSE, 0, 0);
              found = true;
              
              // 等待窗口关闭
              for (int i = 0; i < 10; i++) {
                  if (!IsWindow(hwnd)) break;
                  Sleep(100);
              }
              
              // 如果窗口仍未关闭,强制关闭
              if (IsWindow(hwnd)) {
                  DWORD processId;
                  GetWindowThreadProcessId(hwnd, &processId);
                  HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, processId);
                  if (hProcess) {
                      TerminateProcess(hProcess, 0);
                      CloseHandle(hProcess);
                  }
              }
          }
          
          hwnd = GetWindow(hwnd, GW_HWNDNEXT);
      }
      
      return found;
    }
    
    // 直接使用ShellExecuteA打开URL,更高效
    HINSTANCE startUrl(const char* url) {
      return ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
    }
    
    char baseUrl[7891] = {"https://note.ms/"};
    
    int main() {
      saveOriginalKeyStates();
      atexit(restoreOriginalKeyStates);
      
      int totalRuns;
      cout << "请输入需要运行的次数: ";
      cin >> totalRuns;
      
      if (totalRuns <= 0) {
          cout << "无效的次数,请输入正整数!" << endl;
          return 1;
      }
      
      int cnt = 1;
      cout << "程序开始运行,共需执行 " << totalRuns << " 次..." << endl;
      
      try {
          while (cnt <= totalRuns) {
              // 构建完整网址
              char fullUrl[7891];
              strcpy(fullUrl, baseUrl);
              
              stack<int> num;
              int tmp = cnt;
              while (tmp) {
                  num.push(tmp % 10);
                  tmp /= 10;
              }
              
              int cnt2 = 0;
              while (!num.empty()) {
                  fullUrl[strlen(baseUrl) + cnt2] = num.top() + '0';
                  cnt2++;
                  num.pop();
              }
              fullUrl[strlen(baseUrl) + cnt2] = '\0';
              
              cout << "第 " << cnt << " 次任务: " << fullUrl << endl;
              
              // 启动网页
              HINSTANCE result = startUrl(fullUrl);
              if ((int)result > 32) {  // ShellExecute成功返回值大于32
                  cout << "网页已启动" << endl;
                  Sleep(500);  // 等待网页加载
                  
                  // 先执行粘贴操作(Ctrl+A全选,然后Ctrl+V粘贴)
                  cout << "执行粘贴操作..." << endl;
                  presskey(VK_CONTROL, 0x41);  // Ctrl+A
                  Sleep(30);
                  presskey(VK_CONTROL, 0x56);  // Ctrl+V
                  Sleep(30);  // 等待粘贴完成
                  
                  // 再关闭网页
                  if (closeWindowByTitle("note.ms")) {
                      cout << "网页已关闭" << endl;
                  } else {
                      cout << "关闭网页失败,尝试强制关闭浏览器标签页" << endl;
                      presskey(VK_CONTROL, 0x57); // Ctrl+W
                      Sleep(500);
                  }
              } else {
                  cout << "启动网页失败" << endl;
              }
              
              cnt++;
              if (cnt <= totalRuns) {
                  Sleep(500);  // 两次任务间隔
              }
          }
          
          cout << "所有 " << totalRuns << " 次任务已完成!" << endl;
      } catch (...) {
          restoreOriginalKeyStates();
          throw;
      }
      
      return 0;
    }
    
    

    2. 快乐的小鸟

    特别鸣谢: 2023tyoi0865 (黄子宸)

      #include<bits/stdc++.h>
      #include<windows.h>
      #include<conio.h>
      
      using namespace std;
      
      // 全局变量
      int score = 0;
      int highScore = 0;
      bool gameOver = false;
      HANDLE hOut; // 控制台句柄,用于双缓冲
      int difficulty = 1; // 1-简单, 2-中等, 3-困难, 默认简单 
      
      // 游戏地图大小设置
      const int MAP_WIDTH = 100;   // 宽度
      const int MAP_HEIGHT = 30;   // 高度
      const int MAP_OFFSET = 3;    // 地图上方偏移,预留空间显示分数等信息
      
      // 按键检测宏
      #define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1 : 0)
      
      // 管道结构体 - 修改为竖向管道
      struct Pipe {
          int x;          // 管道的x坐标(水平位置)
          int top_height; // 上管道高度
          int bottom_y;   // 下管道起始y坐标
          int gap;        // 管道中间空隙大小
          bool passed;    // 是否已经被小鸟通过
      };
      
      // 双缓冲相关函数
      void InitConsole() {
          hOut = GetStdHandle(STD_OUTPUT_HANDLE);
          // 设置控制台大小
          char cmd[50];
          sprintf(cmd, "mode con cols=%d lines=%d", MAP_WIDTH + 10, MAP_HEIGHT + 10);
          system(cmd);
      }
      
      // 移动光标到指定位置
      void Gotoxy(int x, int y) {
          COORD pos;
          pos.X = x;
          pos.Y = y;
          SetConsoleCursorPosition(hOut, pos);
      }
      
      // 隐藏光标
      void HideCursor() {
          CONSOLE_CURSOR_INFO cursor_info = {1, 0};
          SetConsoleCursorInfo(hOut, &cursor_info);
      }
      
      // 读取最高分数
      void LoadHighScore() {
          ifstream fin("highscore.txt");
          if (fin.is_open()) {
              fin >> highScore;
              fin.close();
          } else {
              ofstream fout("highscore.txt");
              fout << 0;
              fout.close();
              highScore = 0;
          }
      }
      
      // 保存最高分数
      void SaveHighScore() {
          if (score > highScore) {
              highScore = score;
              ofstream fout("highscore.txt");
              fout << highScore;
              fout.close();
          }
      }
      
      // 显示难度选择界面
      void ShowDifficultyScreen() {
          system("cls");
          Gotoxy(MAP_WIDTH/2 - 8, 5);
          cout << "选择游戏难度";
          
          Gotoxy(MAP_WIDTH/2 - 10, 10);
          if (difficulty == 1) cout << "> ";
          else cout << "  ";
          cout << "1. 简单 (管道稀疏,速度慢)";
          
          Gotoxy(MAP_WIDTH/2 - 10, 12);
          if (difficulty == 2) cout << "> ";
          else cout << "  ";
          cout << "2. 中等 (平衡的挑战)";
          
          Gotoxy(MAP_WIDTH/2 - 10, 14);
          if (difficulty == 3) cout << "> ";
          else cout << "  ";
          cout << "3. 困难 (管道密集,速度快)";
          
          Gotoxy(MAP_WIDTH/2 - 15, 18);
          cout << "按上下方向键选择,按回车确认";
          
          while (true) {
              if (KEY_DOWN(VK_UP) && difficulty > 1) {
                  difficulty--;
                  ShowDifficultyScreen();
                  Sleep(200);
              }
              if (KEY_DOWN(VK_DOWN) && difficulty < 3) {
                  difficulty++;
                  ShowDifficultyScreen();
                  Sleep(200);
              }
              if (KEY_DOWN(VK_RETURN)) {
                  break;
              }
              Sleep(50);
          }
      }
      
      // 显示标题界面
      void ShowTitleScreen() {
          system("cls");
          Gotoxy(MAP_WIDTH/2 - 5, 5);
          cout << "快乐小鸟";
          
          Gotoxy(MAP_WIDTH/2 - 8, 8);
          cout << "最高分: " << highScore;
          
          Gotoxy(MAP_WIDTH/2 - 12, 12);
          cout << "按空格键开始游戏";
          
          Gotoxy(MAP_WIDTH/2 - 12, 14);
          cout << "按S键设置难度";
          
          Gotoxy(MAP_WIDTH/2 - 15, 16);
          cout << "游戏中按空格键控制小鸟上升";
          
          while (true) {
              if (KEY_DOWN(VK_SPACE)) {
                  break;
              }
              if (KEY_DOWN('S') || KEY_DOWN('s')) {
                  ShowDifficultyScreen();
                  ShowTitleScreen();
              }
              Sleep(50);
          }
          system("cls");
      }
      
      // 显示游戏结束界面
      void ShowGameOverScreen() {
          system("cls");
          Gotoxy(MAP_WIDTH/2 - 5, 5);
          cout << "游戏结束!";
          
          Gotoxy(MAP_WIDTH/2 - 8, 8);
          cout << "你的分数: " << score;
          
          Gotoxy(MAP_WIDTH/2 - 8, 9);
          cout << "最高分: " << highScore;
          
          Gotoxy(MAP_WIDTH/2 - 12, 13);
          cout << "按空格键重新开始";
          
          Gotoxy(MAP_WIDTH/2 - 12, 15);
          cout << "按S键设置难度";
          
          Gotoxy(MAP_WIDTH/2 - 10, 17);
          cout << "按ESC键退出";
          
          SaveHighScore();
          
          while (true) {
              if (KEY_DOWN(VK_SPACE)) {
                  score = 0;
                  gameOver = false;
                  break;
              }
              if (KEY_DOWN('S') || KEY_DOWN('s')) {
                  ShowDifficultyScreen();
                  score = 0;
                  gameOver = false;
                  break;
              }
              if (KEY_DOWN(VK_ESCAPE)) {
                  exit(0);
              }
              Sleep(50);
          }
          system("cls");
      }
      
      // 绘制游戏元素
      void DrawGame(int bird_x, int bird_y, Pipe pipes[], int pipeCount) {
          system("cls");
          
          // 绘制分数和难度
          Gotoxy(0, 0);
          cout << "分数: " << score;
          cout << "    最高分: " << highScore;
          cout << "    难度: ";
          if (difficulty == 1) cout << "简单";
          else if (difficulty == 2) cout << "中等";
          else cout << "困难";
          
          // 绘制上下边界
          Gotoxy(0, MAP_OFFSET);
          for (int x = 0; x < MAP_WIDTH; x++) {
              cout << "-";
          }
          
          Gotoxy(0, MAP_OFFSET + MAP_HEIGHT);
          for (int x = 0; x < MAP_WIDTH; x++) {
              cout << "-";
          }
          
          // 绘制小鸟
          Gotoxy(bird_x, MAP_OFFSET + bird_y);
          cout << "鸟";
          
          // 绘制竖向管道
          for (int i = 0; i < pipeCount; i++) {
              // 绘制上管道
              for (int y = 1; y <= pipes[i].top_height; y++) {
                  Gotoxy(pipes[i].x, MAP_OFFSET + y);
                  cout << "|";
              }
              
              // 绘制下管道
              for (int y = pipes[i].bottom_y; y < MAP_HEIGHT; y++) {
                  Gotoxy(pipes[i].x, MAP_OFFSET + y);
                  cout << "|";
              }
          }
          
          FlushConsoleInputBuffer(hOut);
      }
      
      // 游戏主逻辑
      void HappyBird() {
          // 根据难度设置游戏参数
          int pipeCount, gapSize, gameSpeed, gravity, jumpPower;
          
          switch(difficulty) {
              case 1: // 简单
                  pipeCount = 3;    // 管道数量少
                  gapSize = 8;      // 空隙大
                  gameSpeed = 100;  // 速度慢
                  gravity = 1;      // 重力小
                  jumpPower = -3;   // 跳跃力减小,避免跳得太高
                  break;
              case 2: // 中等
                  pipeCount = 5;    // 管道数量中等
                  gapSize = 7;      // 空隙中等
                  gameSpeed = 80;   // 速度中等
                  gravity = 1;      // 重力中等
                  jumpPower = -3;   // 跳跃力减小
                  break;
              case 3: // 困难
                  pipeCount = 7;    // 管道数量多
                  gapSize = 6;      // 空隙小
                  gameSpeed = 60;   // 速度快
                  gravity = 2;      // 重力大
                  jumpPower = -4;   // 跳跃力适中
                  break;
          }
          
          Pipe pipes[pipeCount];
          int pipeSpacing = MAP_WIDTH / (pipeCount + 1); // 管道间距
          
          // 初始化管道(竖向)
          for (int i = 0; i < pipeCount; i++) {
              pipes[i].x = 30 + i * pipeSpacing; // 水平位置
              pipes[i].top_height = rand() % (MAP_HEIGHT - gapSize - 5) + 2; // 上管道高度
              pipes[i].gap = gapSize;
              pipes[i].bottom_y = pipes[i].top_height + gapSize; // 下管道起始位置
              pipes[i].passed = false;
          }
          
          // 小鸟初始位置 - 地图左侧中间
          int bird_x = 15;             // x坐标(水平方向)
          int bird_y = MAP_HEIGHT / 2; // y坐标(垂直方向)
          int falling_speed = 0;       // 下落速度
          
          gameOver = false;
          
          while (!gameOver) {
              // 处理小鸟物理运动
              falling_speed += gravity;
              falling_speed = min(falling_speed, 4); // 限制最大下落速度
              
              // 空格键控制上升
              if (KEY_DOWN(VK_SPACE)) {
                  falling_speed = jumpPower; // 跳跃力减小,解决跳得过高问题
              }
              
              // 更新小鸟位置
              bird_y += falling_speed;
              
              // 检测上下边界碰撞
              if (bird_y <= 1 || bird_y >= MAP_HEIGHT - 1) {
                  gameOver = true;
              }
              
              // 更新管道位置(向左移动)
              for (int i = 0; i < pipeCount; i++) {
                  pipes[i].x--;
                  
                  // 当管道移出屏幕左侧时重置到右侧
                  if (pipes[i].x < 5) {
                      pipes[i].x = MAP_WIDTH - 5;
                      pipes[i].top_height = rand() % (MAP_HEIGHT - gapSize - 5) + 2;
                      pipes[i].bottom_y = pipes[i].top_height + gapSize;
                      pipes[i].passed = false;
                  }
                  
                  // 检测管道碰撞(小鸟与管道在同一x位置)
                  if (abs(pipes[i].x - bird_x) <= 1) {
                      // 检查小鸟是否撞到上管道或下管道
                      if (bird_y <= pipes[i].top_height || bird_y >= pipes[i].bottom_y) {
                          gameOver = true;
                      }
                  }
                  
                  // 检测是否通过管道并加分
                  if (pipes[i].x < bird_x && !pipes[i].passed) {
                      pipes[i].passed = true;
                      score += (difficulty == 3) ? 15 : 10;
                  }
              }
              
              // 绘制游戏画面
              DrawGame(bird_x, bird_y, pipes, pipeCount);
              
              // 控制游戏速度
              Sleep(gameSpeed);
          }
      }
      
      int main() {
          srand(time(0));
          InitConsole();
          HideCursor();
          LoadHighScore();
          
          while (true) {
              ShowTitleScreen();
              HappyBird();
              ShowGameOverScreen();
          }
          
          return 0;
      }
    

    3. 扫雷

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <windows.h>
    #include <queue>
    #include <conio.h>
    #include <cstring>
    using namespace std;
    
    // 全局常量与变量
    const int MAX_SIZE = 60;  // 支持更大尺寸
    bool mine[MAX_SIZE][MAX_SIZE];       // 地雷位置(true为雷)
    int view[MAX_SIZE][MAX_SIZE];        // 显示状态(0:未显示 1:已显示 2:标记)
    int count_mine[MAX_SIZE][MAX_SIZE];  // 周围雷数(-1为雷)
    int dx[8] = {1, -1, 0, 0, 1, 1, -1, -1};
    int dy[8] = {0, 0, 1, -1, 1, -1, 1, -1};
    struct Node { int x, y; };
    HWND console_hwnd;                   // 控制台窗口句柄
    int rows, cols, total_mines;         // 行数、列数、总地雷数
    bool is_started = false;             // 游戏是否开始
    bool left_pressed = false;           // 左键按压状态
    bool right_pressed = false;          // 右键按压状态
    
    // 双缓冲相关
    HANDLE hFront, hBack;                // 前台/后台缓冲区
    COORD buffer_size = {200, 80};       // 扩大缓冲区,适配更大尺寸
    SMALL_RECT window_rect = {0, 0, 199, 79};
    
    // 初始化双缓冲
    void init_double_buffer() {
      hFront = CreateConsoleScreenBuffer(
      								   GENERIC_WRITE,
      								   FILE_SHARE_WRITE,
      								   NULL,
      								   CONSOLE_TEXTMODE_BUFFER,
      								   NULL
      								   );
      hBack = CreateConsoleScreenBuffer(
      								  GENERIC_WRITE,
      								  FILE_SHARE_WRITE,
      								  NULL,
      								  CONSOLE_TEXTMODE_BUFFER,
      								  NULL
      								  );
      SetConsoleScreenBufferSize(hFront, buffer_size);
      SetConsoleScreenBufferSize(hBack, buffer_size);
      SetConsoleWindowInfo(hFront, TRUE, &window_rect);
      SetConsoleWindowInfo(hBack, TRUE, &window_rect);
      SetConsoleActiveScreenBuffer(hFront);
    }
    
    // 输出到指定缓冲区
    void buffer_printf(HANDLE hBuf, int x, int y, const char* str) {
      COORD pos = {static_cast<SHORT>(x), static_cast<SHORT>(y)};
      SetConsoleCursorPosition(hBuf, pos);
      DWORD written;
      WriteFile(hBuf, str, strlen(str), &written, NULL);
    }
    
    // 高效清空缓冲区
    void clear_buffer(HANDLE hBuf) {
      COORD pos = {0, 0};
      DWORD written;
      FillConsoleOutputCharacter(hBuf, ' ', buffer_size.X * buffer_size.Y, pos, &written);
      FillConsoleOutputAttribute(hBuf, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, 
      						   buffer_size.X * buffer_size.Y, pos, &written);
    }
    
    // 交换缓冲区
    void swap_buffers() {
      HANDLE temp = hFront;
      hFront = hBack;
      hBack = temp;
      SetConsoleActiveScreenBuffer(hFront);
    }
    
    // 隐藏光标
    void hide_cursor() {
      CONSOLE_CURSOR_INFO cursor_info = {1, 0};
      SetConsoleCursorInfo(hFront, &cursor_info);
      SetConsoleCursorInfo(hBack, &cursor_info);
    }
    
    // 绘制基础封面(无输入提示,供叠加使用)
    void draw_cover_base() {
      clear_buffer(hBack);
      // 标题
      buffer_printf(hBack, 45, 5, "=======================");
      buffer_printf(hBack, 45, 6, "        扫 雷 游 戏     ");
      buffer_printf(hBack, 45, 7, "=======================");
      // 难度选项
      buffer_printf(hBack, 30, 9, "1. 初级 (9x9, 10雷)");
      buffer_printf(hBack, 30, 10, "2. 中级 (16x16, 40雷)");
      buffer_printf(hBack, 30, 11, "3. 高级 (16x30, 99雷)");
      buffer_printf(hBack, 30, 12, "4. 自定义难度");
      // 基础选择提示
      buffer_printf(hBack, 30, 14, "请选择难度 (1-4): ");
    }
    
    // 绘制完整封面(含输入提示)
    void draw_cover(const char* input_msg = "") {
      draw_cover_base();  // 先绘制基础封面
      if (strlen(input_msg) > 0) {
      	buffer_printf(hBack, 30, 16, input_msg);  // 叠加输入提示
      }
      swap_buffers();
    }
    
    // 初始化游戏数据
    void init_game() {
      for (int i = 1; i <= rows; i++) {
      	for (int j = 1; j <= cols; j++) {
      		mine[i][j] = false;
      		view[i][j] = 0;
      		count_mine[i][j] = 0;
      	}
      }
      is_started = false;
      left_pressed = false;
      right_pressed = false;
    }
    
    // 生成地雷(首次点击安全)
    void generate_mines(int first_x, int first_y) {
      srand((unsigned int)time(0) + rand());
      int generated = 0;
      const int MAX_TRIES = 10000;
      int tries = 0;
      
      for (int i = first_x - 1; i <= first_x + 1; i++) {
      	for (int j = first_y - 1; j <= first_y + 1; j++) {
      		if (i >= 1 && i <= rows && j >= 1 && j <= cols) {
      			mine[i][j] = false;
      		}
      	}
      }
      
      while (generated < total_mines && tries < MAX_TRIES) {
      	tries++;
      	int x = rand() % rows + 1;
      	int y = rand() % cols + 1;
      	if (x >= first_x - 1 && x <= first_x + 1 && y >= first_y - 1 && y <= first_y + 1)
      		continue;
      	if (!mine[x][y]) {
      		mine[x][y] = true;
      		generated++;
      	}
      }
      
      for (int i = 1; i <= rows; i++) {
      	for (int j = 1; j <= cols; j++) {
      		if (mine[i][j]) {
      			count_mine[i][j] = -1;
      			continue;
      		}
      		int sum = 0;
      		for (int d = 0; d < 8; d++) {
      			int nx = i + dx[d];
      			int ny = j + dy[d];
      			if (nx >= 1 && nx <= rows && ny >= 1 && ny <= cols && mine[nx][ny])
      				sum++;
      		}
      		count_mine[i][j] = sum;
      	}
      }
    }
    
    // 展开空白区域
    void expand_area(int x, int y) {
      if (view[x][y] != 0) return;
      queue<Node> q;
      q.push({x, y});
      view[x][y] = 1;
      
      while (!q.empty()) {
      	Node curr = q.front();
      	q.pop();
      	
      	if (count_mine[curr.x][curr.y] != 0) continue;
      	
      	for (int d = 0; d < 8; d++) {
      		int nx = curr.x + dx[d];
      		int ny = curr.y + dy[d];
      		if (nx >= 1 && nx <= rows && ny >= 1 && ny <= cols && view[nx][ny] == 0) {
      			view[nx][ny] = 1;
      			q.push({nx, ny});
      		}
      	}
      }
    }
    
    // 绘制游戏界面
    int draw_game() {
      clear_buffer(hBack);
      int safe_opened = 0;
      char temp[10];
      
      const int GAME_TOP_Y = 4;
      const int GAME_LEFT_X = 20;
      
      buffer_printf(hBack, GAME_LEFT_X, 0, "扫雷游戏(左键揭开,右键标记,ESC退出)");
      buffer_printf(hBack, GAME_LEFT_X, 1, "----------------------------------------");
      
      // 绘制列号(适配大列数)
      buffer_printf(hBack, GAME_LEFT_X, GAME_TOP_Y - 2, "  ");
      for (int j = 1; j <= cols; j++) {
      	if (j < 10) sprintf(temp, " %d", j);
      	else if (j < 100) sprintf(temp, "%d", j);  // 支持两位数列号
      	else sprintf(temp, "%d", j);  // 三位数(虽然很少用)
      	buffer_printf(hBack, GAME_LEFT_X + (j-1)*2, GAME_TOP_Y - 2, temp);
      }
      
      buffer_printf(hBack, GAME_LEFT_X, GAME_TOP_Y - 1, " ");
      for (int j = 1; j <= cols; j++) {
      	buffer_printf(hBack, GAME_LEFT_X + (j-1)*2, GAME_TOP_Y - 1, "--");
      }
      
      for (int i = 1; i <= rows; i++) {
      	if (i < 10) sprintf(temp, " %d|", i);
      	else sprintf(temp, "%d|", i);
      	buffer_printf(hBack, GAME_LEFT_X - 4, GAME_TOP_Y + i - 1, temp);
      	
      	for (int j = 1; j <= cols; j++) {
      		char cell[3] = "  ";
      		if (view[i][j] == 0) {
      			strcpy(cell, "██");
      		} else if (view[i][j] == 1) {
      			if (count_mine[i][j] == -1) {
      				strcpy(cell, "██");
      			} else if (count_mine[i][j] == 0) {
      				strcpy(cell, "  ");
      				safe_opened++;
      			} else {
      				sprintf(cell, " %d", count_mine[i][j]);
      				safe_opened++;
      			}
      		} else {
      			strcpy(cell, "P ");
      		}
      		buffer_printf(hBack, GAME_LEFT_X + (j-1)*2, GAME_TOP_Y + i - 1, cell);
      	}
      }
      
      if (safe_opened == rows * cols - total_mines) {
      	buffer_printf(hBack, GAME_LEFT_X + cols, GAME_TOP_Y + rows/2, "恭喜胜利!3秒后退出...");
      	swap_buffers();
      	Sleep(3000);
      	exit(0);
      }
      
      swap_buffers();
      return GAME_TOP_Y;
    }
    
    // 选择难度(核心修复:保留封面基础元素)
    void select_difficulty() {
      int choice;
      char temp[100];
      while (true) {
      	draw_cover();  // 初始绘制完整封面
      	if (!(cin >> choice)) {
      		cin.clear();
      		cin.ignore(1000, '\n');
      		draw_cover("输入错误,请输入数字1-4!");  // 叠加错误提示
      		Sleep(1000);
      		continue;
      	}
      	
      	if (choice == 1) {
      		rows = 9; cols = 9; total_mines = 10;
      		break;
      	} else if (choice == 2) {
      		rows = 16; cols = 16; total_mines = 40;
      		break;
      	} else if (choice == 3) {
      		rows = 16; cols = 30; total_mines = 99;
      		break;
      	} else if (choice == 4) {
      		// 自定义难度:每次输入前先重绘封面,再叠加当前提示
      		while (true) {
      			draw_cover_base();  // 先画封面基础元素
      			buffer_printf(hBack, 30, 16, "请输入行数(5-30): ");
      			swap_buffers();
      			if (!(cin >> rows) || rows < 5 || rows > 30) {
      				cin.clear();
      				cin.ignore(1000, '\n');
      				draw_cover("行数输入错误(必须5-30),请重新输入!");
      				Sleep(1000);
      				continue;
      			}
      			break;
      		}
      		
      		while (true) {
      			draw_cover_base();  // 重绘封面
      			buffer_printf(hBack, 30, 16, "请输入列数(5-50): ");
      			swap_buffers();
      			if (!(cin >> cols) || cols < 5 || cols > 50) {
      				cin.clear();
      				cin.ignore(1000, '\n');
      				draw_cover("列数输入错误(必须5-50),请重新输入!");
      				Sleep(1000);
      				continue;
      			}
      			break;
      		}
      		
      		while (true) {
      			int max_mine = rows * cols / 3;
      			draw_cover_base();  // 重绘封面
      			sprintf(temp, "请输入地雷数(5-%d): ", max_mine);
      			buffer_printf(hBack, 30, 16, temp);
      			swap_buffers();
      			if (!(cin >> total_mines) || total_mines < 5 || total_mines > max_mine) {
      				cin.clear();
      				cin.ignore(1000, '\n');
      				sprintf(temp, "地雷数输入错误(必须5-%d),请重新输入!", max_mine);
      				draw_cover(temp);
      				Sleep(1000);
      				continue;
      			}
      			break;
      		}
      		break;
      	} else {
      		draw_cover("无效选择,请输入1-4!");
      		Sleep(1000);
      	}
      }
      init_game();
    }
    
    // 禁用右键菜单
    void disable_right_click_menu() {
      HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
      DWORD mode;
      GetConsoleMode(hStdin, &mode);
      mode &= ~(ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
      SetConsoleMode(hStdin, mode);
    }
    
    // 获取控制台字体尺寸
    void get_console_font_size(int& font_width, int& font_height) {
      HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
      CONSOLE_FONT_INFOEX cfi;
      cfi.cbSize = sizeof(CONSOLE_FONT_INFOEX);
      GetCurrentConsoleFontEx(hOut, FALSE, &cfi);
      font_width = cfi.dwFontSize.X;
      font_height = cfi.dwFontSize.Y;
    }
    
    // 计算鼠标位置对应的格子坐标
    void get_grid_pos(int& grid_x, int& grid_y) {
      POINT mouse_screen;
      GetCursorPos(&mouse_screen);
      ScreenToClient(console_hwnd, &mouse_screen);
      
      int font_width, font_height;
      get_console_font_size(font_width, font_height);
      
      int buffer_x = mouse_screen.x / font_width;
      int buffer_y = mouse_screen.y / font_height;
      
      const int GAME_LEFT_X = 20;
      const int GAME_TOP_Y = 4;
      
      grid_x = buffer_y - GAME_TOP_Y + 1;
      grid_y = (buffer_x - GAME_LEFT_X) / 2 + 1;
    }
    
    int main() {
      console_hwnd = GetConsoleWindow();
      init_double_buffer();
      hide_cursor();
      disable_right_click_menu();
      
      select_difficulty();
      int game_top_y = draw_game();
      
      while (true) {
      	if (GetAsyncKeyState(VK_LBUTTON) & 0x8000 && !left_pressed) {
      		left_pressed = true;
      		int grid_x, grid_y;
      		get_grid_pos(grid_x, grid_y);
      		
      		if (grid_x >= 1 && grid_x <= rows && grid_y >= 1 && grid_y <= cols) {
      			if (!is_started) {
      				generate_mines(grid_x, grid_y);
      				is_started = true;
      			}
      			
      			if (view[grid_x][grid_y] == 0) {
      				if (count_mine[grid_x][grid_y] == -1) {
      					buffer_printf(hBack, 50, 20, "BOOM! 游戏结束!3秒后退出...");
      					swap_buffers();
      					Sleep(3000);
      					return 0;
      				}
      				expand_area(grid_x, grid_y);
      			} else if (view[grid_x][grid_y] == 2) {
      				view[grid_x][grid_y] = 0;
      			}
      			game_top_y = draw_game();
      		}
      		Sleep(50);
      	} else if (!(GetAsyncKeyState(VK_LBUTTON) & 0x8000)) {
      		left_pressed = false;
      	}
      	
      	if (GetAsyncKeyState(VK_RBUTTON) & 0x8000 && !right_pressed) {
      		right_pressed = true;
      		int grid_x, grid_y;
      		get_grid_pos(grid_x, grid_y);
      		
      		if (grid_x >= 1 && grid_x <= rows && grid_y >= 1 && grid_y <= cols && view[grid_x][grid_y] != 1) {
      			view[grid_x][grid_y] = (view[grid_x][grid_y] == 0) ? 2 : 0;
      			game_top_y = draw_game();
      		}
      		Sleep(50);
      	} else if (!(GetAsyncKeyState(VK_RBUTTON) & 0x8000)) {
      		right_pressed = false;
      	}
      	
      	if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
      		buffer_printf(hBack, 50, 20, "游戏已退出");
      		swap_buffers();
      		Sleep(1000);
      		return 0;
      	}
      	
      	Sleep(10);
      }
      
      return 0;
    }
    
    网站大全
    有用的网站

    网址导航

    开发者导航

    奇趣网站收藏

    孟坤·个人网站创作(HTML)

    b站up主の网盘各类资源

    fmhy资源网

    yandex搜索引擎

    整蛊网站

    在线电脑恶作剧(记得全屏加关翻译)

    算法演示

    图演示

    搜索演示

    算法演示

    字体编辑

    LATEXLATEX 字体

    手写LATEXLATEX

    KATEXKATEX 字体?

    洛谷 LATEXLATEX 大全

    ASCLLASCLL 字体

    Markdown练习

    学习网页

    教材

    OI 维基

    演讲学习

    交互式编程课

    哲学名著解读

    法律条款解析

    菜鸟教程

    c 语言中文网

    关于数学

    数学Desmos

    尺规作图 答案

    更多数学工具

    数学游乐场

    学术科研

    文献引用生成

    古籍全文检索

    论文语法修正

    科研图表库

    代码开发

    正则表达式测试(支持PCRE/Python语法)

    随机数据生成器

    可视化代码(Python/Java/C++代码动画演示)

    SQL练习平台

    在线看汇编

    扩展&插件

    edge

    管理扩展

    获取扩展

    Google

    管理扩展

    获取扩展(应用商店)

    获取插件

    创意设计

    故障艺术生成器

    ASCII艺术转换

    像素动画工具

    配色工具

    数据可视化

    动态图表生成

    关系图谱分析

    CSV可视化工具

    音乐创作

    AI人声分离

    在线合成器

    律动生成器

    趣味工具

    地球实时天气1

    (〃'▽'〃) 我收录了两个 牛不牛逼

    地球实时天气2

    3D桌面模拟器

    3D开车模拟器

    AI写小说

    手机桌面1

    (〃'▽'〃) 我收录了两个 牛不牛逼 X2

    手机桌面2

    文件管理

    临时网盘

    批量重命名

    磁盘分析

    隐私安全

    临时邮箱

    密码强度测试

    隐私检测

    效率增强

    剪贴板历史

    全局搜索

    鼠标手势

    主页壁纸调用

    二次元图片库

    二次元图片调用

    其他

    文言文加密

    文本比对

    Luogu原题机

    剪切板

    表情大全

    鼠标图片定位

    AI查重

    软件纯净下载

    好臭的数字

    沙雕APP

    致美化

    整理不了太多e,自行去他主页找吧,就是我懒

    腐朽网址(被抓与我无关)

    虚拟游乐园

    AK-IOI

    florr小花花

    桌游合集

    随机英文网页

    MC网页版

    扫雷

    开源 React 游戏

    经典益智游戏

    好康的图片

    图片都是我从别人主页勤奋收集来的,不乐意或侵权 (有侵权这玩意儿吗🤔) 可删

    史官记录
    1. 真实记录~~是她被JC了~~

    2. 二次JC

    3. 又一个受害者

    4. 奇妙豌豆黄

    5. 被JC了~~是我干的~~

    6. 这。。。

    7. 奇妙的帖子

    8. 优先队列。。。

    9. 猎奇

    梗图

    讲个笑话:

    逆天发言

    陈年老题:

    抽象发言:

    猫梁哦:

    主页全图:

    剪切板

    字符颜色

      <font color = >
    
    </front>
    

    改网页字符

    document.body.contentEditable = 'true';
    
    document.body.contentEditable = 'false';
    

    include:

    #include <cassert>
    #include <cctype>
    #include <cerrno>
    #include <cfenv>
    #include <cfloat>
    #include <cinttypes>
    #include <ciso646>
    #include <climits>
    #include <clocale>
    #include <cmath>
    #include <csetjmp>
    #include <csignal>
    #include <cstdalign>
    #include <cstdarg>
    #include <cstddef>
    #include <cstdint>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cstdbool>
    #include <ctgmath>
    #include <ctime>
    #include <cuchar>
    #include <cwchar>
    #include <cwctype>
    #include <ccomplex>
    
    #include <exception>
    #include <stdexcept>
    #include <system_error>
    #include <typeinfo>
    #include <type_traits>
    #include <utility>
    #include <new>
    #include <memory>
    #include <memory_resource>
    #include <scoped_allocator>
    
    #include <array>
    #include <vector>
    #include <deque>
    #include <list>
    #include <forward_list>
    #include <set>
    #include <unordered_set>
    #include <map>
    #include <unordered_map>
    #include <stack>
    #include <queue>
    #include <bitset>
    
    #include <iostream>
    #include <ios>
    #include <iosfwd>
    #include <istream>
    #include <ostream>
    #include <fstream>
    #include <sstream>
    #include <streambuf>
    #include <iomanip>
    
    #include <algorithm>
    #include <numeric>
    #include <functional>
    #include <iterator>
    #include <ranges>
    
    #include <string>
    #include <string_view>
    #include <charconv>
    
    #include <complex>
    #include <valarray>
    #include <random>
    #include <ratio>
    #include <chrono>
    #include <bit>
    
    #include <thread>
    #include <mutex>
    #include <condition_variable>
    #include <future>
    #include <atomic>
    #include <latch>
    #include <barrier>
    #include <semaphore>
    
    #include <filesystem>
    #include <span>
    #include <variant>
    #include <any>
    #include <optional>
    #include <source_location>
    #include <concepts>
    #include <compare>
    #include <coroutine>
    

    pragma:

    #pragma GCC optimize("O0")
    #pragma GCC optimize("O1")
    #pragma GCC optimize("O2")
    #pragma GCC optimize("O3")
    #pragma GCC optimize("Os")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("Og")
    #pragma GCC optimize("O2,unroll-loops")
    #pragma GCC optimize("O3,no-tree-vectorize")
    #pragma GCC optimize("fast-math")
    #pragma GCC push_options
    #pragma GCC optimize("O3")
    #pragma GCC pop_options
    #pragma GCC optimize("O3")
    #pragma GCC diagnostic ignored "-Wstrict-aliasing"
    #pragma vectorize(enable)
    #pragma vectorize(disable)
    #pragma optimize("", off)
    #pragma optimize("g", on)
    #pragma optimize("s", on)
    #pragma optimize("t", on)
    #pragma optimize("o", on)
    #pragma optimize("gt", on)
    #pragma push()
    #pragma optimize("o", on)
    #pragma pop()
    #pragma loop(hint_parallel(8))
    #pragma loop_count(max=1000)
    
    下载

    小熊猫 Dev-C++ (仅windows版本) 分享码:f0tp

    MineCraft

    极域杀手 + 夕颜若雪工具箱 密码:86tk

    极域通用密码: mythware_super_password

    主页简介

    luogu | qwerhh

    florr van+ | Ju_RO | 欧

    2025/9/14 主页 2200022000 字啦

    2025/9/21 主页字数 1500015000 倒退啦

    2025/10/4 florr{\color{white}florr} {\color{white}|} Yucca×20{\color{red}Yucca_{\times 20}}

    2025/10/5 florr{\color{white}florr} {\color{white}|} Triangle×100{\color{red}Triangle_{\times 100}} synthesizesynthesize Triangle×3{\color{Turquoise}Triangle_{\times 3}}

    2025/10/7 21:20 访客计数器 10001000我自己刷的

    2025/10/21 访客计数器 20002000

    2025/10/31 14:09 访客计数器 30003000

    2025/11/2 主页 3700037000 字啦

    2025/11/?? 主页一些 超链接&图片失效 ,现已修正

    2025/11/16 访客计数器重置了

    2025/11/2 主页水到 5300053000 字啦

    @

  • 最近活动

  • Stat

  • Rating