首页 > 其他分享 >模拟五

模拟五

时间:2023-10-31 22:44:18浏览次数:27  
标签:GCC int sum pragma optimize 模拟 define

收官之战!!!

模拟赛五补题报告

日期:\(2023\)—\(10\)—\(6\) 学号:\(S11390\)

一、总分:

\(T1\) 重复判断:\(100\)分

\(T2\) 歪果仁学乘法:\(100\)分

\(T3\) 去重求和:\(40\)分

\(T4\) 点集操作:\(0\)分

共:\(240\) 分

二、比赛过程

  • 在第一题中,我在考试中通过遍历字符串的方式,一个一个向下遍历,找到了就接着向下遍历,只要有一个字符不同就跳出遍历,输出 \(NO\)。通过这种简单的思路,也是做对了这道题,成功 \(AC\)。

  • 在第二题中,思路也是很简单,将这个图一画就能够想出思路,也是做对了,成功 \(AC\)。

  • 在第三题中,想不出好的思路,就只能往前几个测试点考虑,得部分分,通过双层循环和前缀和的优化,过了前 \(8\) 个样例,得了 \(40\) 分。

  • 在第四题中,读了几遍后,没有啥思路,就放弃了,没有得分。

三、题目分析

\(T1\) 重复判断

给定两个字符串 \(s,c\) 看看 \(s\) 是否是又 \(c\) 复制而来的,就如果是输出 \(YES\),反之输出 \(NO\)。

我们就可以遍历 \(s\) 字符串,与 \(c\) 字符串相判断,如果有不同那么就输出 \(NO\)。

但要注意:如果 \(s\) 字符串的长度不是 \(c\) 字符串的长度的倍数的话,那么也要输出 \(NO\)。

若前两种情况都满足的话,就输出 \(YES\)。

正解

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define swap(a, b) a ^= b, b ^= a, a ^= b
#define pb push_back

const int N = 1e6 + 10;

int t;

signed main()
{
	//freopen("repeat.in","r",stdin);
	//freopen("repeat.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--)
	{
		int h=0;
		bool flag=1;
		string s,c;
		cin>>s>>c;
		for(int i=0;i<s.size();i++)
		{
			if(s[i]!=c[h])
			{
				flag=0;
				break;
			}
			else
			{
				if(h==c.size()-1)
				{
					h=0;
				}
				else
				{
					h++; 
				}
			}
		}
		if(flag&&s.size()%c.size()==0)  // s 字符串必须是 c 字符串长度的倍数 
		//所以才可能是重复若干次得到的 
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
	 // fclose(stdin);
	  //fclose(stdout);
	return 0;
}

\(T2\) 歪果仁学乘法

如图

给定不超过 \(99\) 的两个数,按照以下方法进行计算。

  • \(a\) 的十位用 \(x1\) 表示,各位用 \(x2\) 表示;\(b\) 的十位用 \(y1\) 表示,各位用 \(y2\) 表示。

  • 间隔一定距离朝同一方向(斜向)画 \(x1\) 和 \(x2\)。

  • 向垂直方向画出 \(y1\) 和 \(y2\)。

  • 数出交点即为答案。

我们可以根据图来看出本题的答案就是将一个公式:
x1*y1 + x2*y1 + x1*y2 + x2*y2;

正解

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>

using namespace std;

#define int unsigned long long
#define swap(a, b) a ^= b, b ^= a, a ^= b
#define pb push_back

const int N = 1e6 + 10;

int a,b;

signed main()
{
    //	freopen("multiplication.in","r",stdin);
    //	freopen("multiplication.out","w",stdout);
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin>>a>>b;
	int x1=a/10,x2=a%10,y1=b/10,y2=b%10;
	//        2*3     3*3     2*2     3*2
	int sum= x1*y1 + x2*y1 + x1*y2 + x2*y2;
	cout<<sum<<endl;
    //  fclose(stdin);                                                                          
    //  fclose(stdout);
    return 0;
}

\(T3\) 去重求和

本题就是让我们求出区间 \([l,r]\) 的数去重后的和,

\(\begin{aligned} \sum _ {i = 1} ^ n \end{aligned}\) \(\begin{aligned} \sum _ {j = 1} ^ i \end{aligned}\) \(sum(i,j)\)

对 \(1e9+7\) 取余的结果。

如果没有去重条件的话,则答案为。

\(sum(1,1)\)

\(sum(1,2)\) \(sum(2,2)\)

\(sum(1,3)\) \(sum(2,3)\) \(sum(3,3)\)

\(\dots\dots\)

\(sum(1,n-1)\) \(sum(2,n-1)\) \(sum(3,n-1)\) \(\dots\) \(sum(n-1,n-1)\)

\(sum(1,n)\) \(sum(2,n)\) \(sum(3,n)\) \(\dots\) \(sum(n,n)\)

此时我们就可以得出公式:

f[i]=f[i-1]+a[i]*i

但这是没去重的情况,加入去重后,需要加入几个条件:我们在遍历数组时,通过 \(map\) 记录一下该数出现的位置,每个重复的元素只累加第一次出现的值。
有了这一条件,我们可以将以 \(i\) 结尾的区间 \(a_i\) 的值进行累加,具体来说,对于一个区间 \([i,x]\),如果出现不止一次 \(a_x\) 那么后面这个 \(a_x\) 控制的只是对于后面出现的与前面出现的这一区间有影响, 区间 \([i,x]\) 中最后一次出现的 \(a_x\) 一定影响了最多的贡献值,并且包含了此前出现的所有 \(a_x\) 带来的影响。

这样说不好理解,我来画个图。

前面的 \(4\) 管前面的区间,后面的 \(4\) 管两个 \(4\) 之间的区间,所以递推公式就找出来了。

f[i]=f[i-1]+a[i]*(i-mp[a[i]])

最后将 \(f_i\) 加起来即为最后的答案。

正解

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>

using namespace std;

#define int unsigned long long
#define swap(a, b) a ^= b, b ^= a, a ^= b
#define pb push_back

const int N = 1e6 + 10;
const int mod = 1e9+7;

map<int ,int > mp;
int a[N];
int n;
int s[N];
int res;

signed main()
{
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		s[i]=s[i-1]+a[i]*(i-mp[a[i]]);
		//每出现一个数就记录一下位置 
		mp[a[i]]=i;
	}
	for(int i=1;i<=n;i++)
		res=(res+s[i])%mod;
	cout<<res<<endl;
    //  fclose(stdin);
    //  fclose(stdout);
    return 0;
}

\(T4\) 点集操作

哎呀,经典的图论题,经典的爆零,也是没有一点思路啊,骗分都不会骗。那我就顺着思路来试着说说这道题。

这道题要通过规律来找到最优解。

  • 对于入度为 \(0\) 的点,那些点一定是能够留下的。

  • 对于由于有入度和出度的点,我们要将它指向的点删除。

  • 对于有多种路径能够到达的点,我们要求到达这个点的最大值,通过最大值看看是否能保留。我们来定义一个广义的深度。如果当前结点的深度 \(>=2\) 时,这个点就删除,否则的话就保留。

最少的点一共有 \(3\) 个,就通过这样的方式减少能够减少的点,最后剩下的就是最少的点。

正解

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=1e6+5;
int n,m,x[MAXN<<1],y[MAXN<<1],in[MAXN];
int head[MAXN],num,ans;
bool b[MAXN],vis[MAXN];
vector<int>v;
queue<int>q;
struct node{
int to,next;
}e[MAXN<<1];
void add(int u,int v){//把边插入进去,用结构体的写法,之前用过 
    e[++num].to=v;
    e[num].next=head[u];
    head[u]=num;
}
int main(){
    cin >> n >> m;
    for(int i=1;i<=m;++i){
        cin >> x[i] >> y[i];//这里用数组存一下,后面方便处理 
        add(x[i],y[i]);
        in[y[i]]++;//统计这个点的入度 
    }
    for(int i=1;i<=n;++i){
        if(!in[i]){//第i个点的入度为0,那就是起始点,计数 
            v.push_back(i);//然后把入度为0的点记下来 ,放到v里 
            ans++;//计数
        }
    }
    for(int i=1;i<=m;++i){//遍历输入的m条边 
        if(in[x[i]])//如果这条边的起点的入度不为0,你们这条边的终点一定不是处于第二层的点,最少也得是第三层   x-->y  x入度不为0,还有点,你们y最少也得在第三层 
			b[y[i]]=1;//那么这个点就不能计数  标记了 
    }
    for(int i=0;i<v.size();++i){//遍历那些没有入度的点,也就是起始点 
        for(int j=head[v[i]];j;j=e[j].next){//找这个点的所有邻接点 
            if(!b[e[j].to]){//如果这个点被标记过,说明这个点不光是起点的下一个点,还是另一个起点的第三层甚至更多的层   没标记过说明就是处于第二层 
                b[e[j].to]=1;
                ans++;//,处于第二层就会计数,这些点虽然会被删除,但是他们可以充当新点,相当于保留
            }
        }
    }
    cout << ans;
    return 0;
}

标签:GCC,int,sum,pragma,optimize,模拟,define
From: https://www.cnblogs.com/gongyuchen/p/17801848.html

相关文章

  • 飞行模拟机--波音机型FMS的入门级操作
    传统的飞行管理系统FMS(FlightManagementSystem),包括飞管计算机FMC(FlightManagementComputer)和控制显示组件CDU(Control&DisplayUnit)。我们先从波音737-800开始了解飞行管理系统FMS的入门使用方法。地点选择杭州萧山机场(四字代码ZSHC),06号跑道。进入游戏后,shift+2......
  • 「解题报告」2023-10-30 模拟赛
    1.ABBA企鹅豆豆拿到了一个\(N\timesM\)的矩阵,每个位置要么是\(A\)要么是\(B\)。他希望尽可能少的改变里面的字(即\(A\)变\(B\)或者\(B\)变\(A\))使得这个矩阵有至少\(R\)行是回文串,以及至少\(C\)列是回文串,现在他想知道自己需要的最少操作次数。枚举哪些行和哪......
  • ​飞行模拟机使用入门—X-Plane使用介绍
    偶然的机会深刻体会了飞行程序规划与模拟机中的路径之间经常存在的显著差异,于是开始考虑深入了解一下飞行模拟机。搜索之后,发现当下主流的模拟游戏X-Plane、FlightGear等,一定程度上已经具备了飞行模拟机所需的基础功能,高仿真的界面、高仿真的操作流程,可更新的数据库,支持多......
  • 模拟实现二叉搜索树(非kv模式)(上)
    本篇博客主要是讲解什么是二叉搜索树,以及模拟实现二叉搜索树的插入节点,中序遍历,查找特定节点,以及删除节点。什么是二叉搜索树首先二叉搜索树肯定是一棵二叉树,对于二叉树我们应该是陌生了。而我们在学习二叉树的时候知道,如果只是一棵普通的二叉树,用来储存数据是没有任何意义的,因为如......
  • Windows安装Waymo自动驾驶模拟器
    https://github.com/waymo-research/waymax1.pip安装Waymaxpipinstall--upgradepippipinstallgit+https://github.com/waymo-research/waymax.git@main#egg=waymo-waymaxGitHub仓库一直连接超时,故采用先clone下来再安装的做法:gitclonehttps://github.com/waymo-r......
  • 23/10/29 模拟赛总结
    时间安排7:35-8:20直接开T1,发现不会做。8:20-8:40把T2T3T4都看了,T2和T1一样是我必不可能会的人类智慧题,T3看上去就很劝退,T4是我喜欢的树上问题,直接倒序开题。8:40-10:20想了T4,得到了一个\(O(n^2)\)的暴力,高达40分,直接开写。写完之后过不了第二个样例,发现假......
  • 开放寻址法模拟散列表
    文章目录QuestionIdeasCodeQuestion维护一个集合,支持如下几种操作:Ix,插入一个整数x;Qx,询问整数x是否在集合中出现过;现在要进行N次操作,对于每个询问操作输出对应的结果。输入格式第一行包含整数N,表示操作数量。接下来N行,每行包含一个操作指令,操作指令为Ix,Qx中的......
  • CSP模拟57联测19_全球覆盖
    题面:赛时给我搞破防了,没有一点思路。Part1对于这四种神奇有病的操作,可以把\(x\)轴和\(y\)轴分开考虑,它们之间互不影响。最后答案就是\(x\)轴上的最长距离乘\(y\)轴上的最长距离。这样就把二维的问题拆分成了两个序列上的问题。现在问题变成了给定几个区间,可以取区间的......
  • 手把手教你:如何用Java多线程模拟银行叫号服务
    大家好,我是小米!今天,我将和大家一起探讨一个非常有趣的话题——Java多线程模拟银行叫号服务。这不仅是一个有趣的编程练习,还可以帮助我们更好地理解多线程编程和并发控制。在这篇文章中,我将带领大家一步步实现一个模拟银行叫号服务系统,包括三个窗口、按叫号顺序依次到窗口服务、每个......
  • 10.28 模拟赛小记
    梦熊10连测的第八个了。比赛地址写在亲前面的总结:因为下午班级合唱比赛,所以不太想打比赛,想去看演出的。鉴于我们第一个唱完,以及班主任说节目可以看到15:40,所以一直在玩上去的很晚。之后在机房继续看完了节目。所以本场打的还挺抽象。更加难评的是这竟然是我打的最好的一场(?),有......