深入浅出程序设计竞赛(洛谷基础篇) 第八章 模拟与高精度

电子版教材链接
我通过百度网盘分享的文件:深入浅出程序设计…pdf
链接:https://pan.baidu.com/s/1kmF8wZLnK3Zci7s1ffjRzw
提取码:Ra3Q
复制这段内容打开「百度网盘APP即可获取」

本章大多都是模拟题,没有用到很高深的算法,主要都是用朴素的思维来解决问题,仅仅本文的题目不足以掌握模拟的精髓,希望读者可以多练一些模拟题来升华自己的思维
例8-1 乒乓球
// 法一: 简洁实现
#include<iostream>
#include<cmath>
using namespace std;

char str[100010];
int cnt=0;

  
void show(int n){
   
   
	int a=0,b=0;
	for(int i=0;i<cnt;i++){
   
   
		if(str[i]=='W') a++;
		if(str[i]=='L') b++;
		if((a>=n||b>=n)&&abs(a-b)>=2){
   
   
		cout<<a<<":"<<b<<endl;
		a=b=0;
		}
	}
	//新的一轮刚开始,或上一局没有打完
	cout<<a<<":"<<b<<endl;
}

  

int main(){
   
   
	char ch;
	while(cin>>ch&&ch!='E'){
   
   
		if(ch=='W'||ch=='L'){
   
   
			str[cnt++]=ch;
		}
	}
	
	show(11);
	cout<<endl;
	show(21);
	return 0;
}

// 法二:完整实现
#include <bits/stdc++.h>
using namespace std;
char n;
int l,m;
int a[62503];
int main()
{
   
   
	for(int i = 0;cin >> n && n != 'E';i++)
	{
   
   
		if(n == 'W') a[i] = 1;
		if(n == 'L') a[i] = 2;
	}
	// 11分制
	for(int i = 0;1;i++)
	{
   
   
		if(a[i] == 1) l++;
		if(a[i] == 2) m++;
		if(a[i] == 0)
		{
   
   
			cout << l << ":" << m << endl << endl;
			break;
		}
		if(l - m >= 2 || m - l >= 2)
		{
   
   
			if(l >= 11 || m >= 11)
			{
   
   
				cout << l << ":" << m << endl;
				l = 0;
				m = 0;
			}
		}
	}
	
	l = 0;
	m = 0;
	
	// 21分制
	for(int i = 0;1;i++)
	{
   
   
		if(a[i] == 1) l++;
		if(a[i] == 2) m++;
		if(a[i] == 0)
		{
   
   
			cout << l << ":" << m << endl;  //把未打完的残局也输出出去
			break;
		}
		if(l - m >= 2 || m - l >= 2)
		{
   
   
			if(l >= 21 || m >= 21)
			{
   
   
				cout << l << ":" << m << endl;
				l = 0;
				m = 0;
			}
		}
	}
	return 0;
}
例8-2 扫雷游戏
// 法一:开桶
#include <bits/stdc++.h>
using namespace std;
int n,m;
char arr[105][105];

const int dx[]  = {
   
   1,1,1,0,0,-1,-1,-1};
const int dy[] = {
   
   -1,0,1,-1,1,-1,0,1};

// 这边定义了该点周围八个方向的点的偏移量

int main()
{
   
   
    cin >> n >> m;
    for(int i = 1;i<=n;i++)
    {
   
   
        for(int j = 1;j<=m;j++)
        {
   
   
            cin >> arr[i][j];
        }
    }
    for(int i = 1;i<=n;i++)
    {
   
   
        for(int j = 1;j<=m;j++)
        {
   
   
            if(arr[i][j] != '*')
            {
   
   
                int cnt = 0;
                for(int k = 0;k<8;k++)
                {
   
   
                    if(arr[i+dx[k]][j+dy[k]] == '*') cnt++;
                }
                cout << cnt;
            }
            else cout << '*';
        }
        cout << endl;
    }
    return 0;
}

// 法二:dfs
#include <bits/stdc++.h>
using namespace std;
int n,m;
char arr[105][105];

void dfs(int x,int y){
   
   //需要返回空类型,定义void函数 
    if(arr[x][y]=='0'){
   
   
        for(int dx=-1;dx<=1;dx++){
   
   
            for(int dy=-1;dy<=1;dy++){
   
   
                int nx=dx+x,ny=dy+y;
                if(0<=nx&&nx<n&&0<=ny&&ny<m&&arr[nx][ny]=='*')//八连通循环 ,且必须不越界
                arr[x][y]+=1;//如果是雷的话将那一个点加1 
            }
        }
    }
    return;//将那个点加完之后就返回继续找下一个点 
} 
int main()
{
   
   
    string s;
    cin >> n >> m;
    for(int i = 0; i < n; i++)
    {
   
   
        cin >> s;
        for(int j = 0; j < m; j++)
        {
   
   
            arr[i][j] = s[j];
            if(arr[i][j] == '?')
	        {
   
   
	            arr[i][j] = '0';
	        }
        }
    }
    for(int i = 0;i<n;i++)
    {
   
   
        for(int j = 0;j<m;j++)
            dfs(i,j);
    }
    for(int i=0;i<n;i++){
   
   
        for(int j=0;j<m;j++)
            cout<<arr[i][j];//按序输出每一个点 
        cout << endl;
    }
    return 0;
}
例8-3 玩具谜题
#include <bits/stdc++.h>
using namespace std;

struct nihao{
   
   
	bool dict;
	string name;
}arr[100005];

int main()
{
   
   
	bool s;
	int len,cnt = 0; // cnt表示的是最后我们要找的人的索引
	cin >> n >> m;
	for(int i = 0;i<n;i++)
	{
   
   
		cin >> arr[i].dict >> arr[i].name;
	} 
	for(int i = 0;i<m;i++)
	{
   
   
		cin >> s >> len; // 0表示左数,1表示右数 ;其中朝内向左等价于朝外向右,即00和11是一致的,我们主要考虑朝内向右为正 01
		if(arr[cnt].dict == 0 && s== 0 || arr[cnt].dict == 1 && s == 1)
		{
   
   
			cnt -= len;
		}
		else
			cnt += len;
		if(cnt >=n)
			cnt-=n;
		else if(cnt<0)
			cnt+=n;
	}
	cout << arr[cnt].name << endl;
	return 0;
}
例8-4 高精度加法

直接使用取模的方式从低位往高位进行进位,这里是高精度加上高精度

#include <bits/stdc++.h>
using namespace std;
#define maxn 520
int a[maxn],b[maxn],c[maxn];

int main()
{
   
   
	string A,B;
	cin >> A >> B;
	int len = max(A.length(),b.length());
	for(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值