首页 > 其他分享 >2024.3.31补题

2024.3.31补题

时间:2024-03-31 18:13:10浏览次数:20  
标签:p2 2024.3 int s2 31 long s3 补题 &&

SMU 2024 spring 天梯赛2(补题)

https://pintia.cn/problem-sets/1772539187410104320/exam/overview
7-10 红色警报

错误:
① 没写
② 用的unordered_map<>判断的联通条件。只要有城市和它相连就判它在城市群里,只对了样例。。。
③ 不会深搜。。。

#include<bits/stdc++.h>
using namespace std;
int degree[510];
int G[510][510];
int vis[510];//访问标记。
int del[510];//占领标记。
int n,k;

void dfs(int step)
{
	for(int i=0;i<n;i++)
	{
		if(vis[i]==0 and del[i]==0 and G[step][i])
		{//如果这个点没有被标记过,并且没有被占领过,并且他和这个传入城市点联通;
			vis[i]=1;
			dfs(i);
		//只要联通的城市没有被扫完,那么就一直搜索。
		}
	}
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	cin>>n>>k;
	for(int i=0;i<k;i++)
	{
		int x,y;
		cin>>x>>y;
		G[x][y]=G[y][x]=1;
		//建立联通状况
	}
	int num_line=0;
	for(int i=0;i<n;i++)
	{
		//起始第一个点一定会被加,即使全部联通总数也会是1.
		if(vis[i]==0)
		{
			vis[i]=1;
			num_line++;
			dfs(i);
		}
		//通过深搜来避免城市的错误统计。
	}
	int m;
	cin>>m;
	for(int i1=0;i1<m;i1++)
	{
		int x;
		cin>>x;
		for(int i=0;i<n;i++)
		{
			if(G[x][i]==1)
			{
				G[x][i]=G[i][x]=0;
			}
			//删去被占领城市的联通城市。
		}
		del[x]=1;
		memset(vis,0,sizeof(vis));
		int num_line_after=0;
		for(int i=0;i<n;i++)
		{
			if(vis[i]==0 and del[i]==0)
			{
				vis[i]=1;
				num_line_after++;
				dfs(i);
			}
			//同样用深搜来查找城市块个数
		}
		if(num_line<num_line_after)
			cout<<"Red Alert: City "<<x<<" is lost!\n";
		else
			cout<<"City "<<x<<" is lost.\n";
		num_line=num_line_after;
		if(i1==n-1)
			cout<<"Game Over.\n";
	}
	return 0;
}

memset函数及其用法

void *memset(void src, int value, size_t n);
这里srs可以是数组名,也可以是指向某一内存空间的指针;
value为要填充的值;
n为要填充的字节数,通常为sizeof(s);
函数的功能:将指针变量 src 所指向的前 n 字节的内存单元用一个“整数” value 替换,注意 value是 int 型。src 是 void
型的指针变量,所以它可以为任何类型的数据进行初始化。

解释memset(a,'0',sizeof(a)); 的意思
这条语句是把a中所有字节换做字符“0”,常用来对指针或字符串的初始化。


7-11 排座位


-_-*如果if(),else if()...else if();最后某个选项结果不合预期时可以是这个把最后一个换成else...(天梯)。。。分数从4变到了22。。。


这里的代码设置了两个初始数组,mp用来存放两个人彼此的关系情况,fri用来保存两个人是否为朋友。
利用三重循环,对于每一个人,以其为中间人,遍历他的所有朋友和所有以他为朋友的人,将这些人的关系网全都扩展开(朋友的朋友也是朋友)。

接着按照题目的要求。如果两个宾客间是。。。那么。。。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
int mp[200][200],fri[200][200];

int main()
{
	int n,m,k;
	cin>>n>>m>>k;
	int a,b,c;
	for(int i=1;i<=m;i++)
	{
		cin>>a>>b>>c;
		mp[a][b]=c;
		mp[b][a]=c;
		if(c==1)
		{
			fri[a][b]=c;
			fri[b][a]=c;
		}
	}
	for(int z=1;z<=n;z++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(fri[i][z]==1&&fri[z][j]==1)
				{
					fri[i][j]=1;
				}
			}
		}
	}
	while(k--)
	{
		cin>>a>>b;
		if(mp[a][b]==-1&&fri[a][b]==0)
		{
			cout<<"No way"<<endl;
		}else if(mp[a][b]==-1&&fri[a][b]==1)
		{
			cout<<"OK but..."<<endl;
		}else if(mp[a][b]==0)
		{
			cout<<"OK"<<endl;
		}else
		{
			cout<<"No problem"<<endl;
		}
	}

	return 0;
}

unordered_map解法:
设立结构体数组,存放每个人的敌和友,对于每个人遍历他所有朋友的所有朋友。最后按要求来^_^

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct p
{
	unordered_map<int,int>di;
	unordered_map<int,int>you;
};
int main()
{
	int n,m,k;
	cin>>n>>m>>k;
	vector<p>s(n+1);
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		if(c==-1)
		{
			s[a].di[b]++;
			s[b].di[a]++;
		}else if(c==1)
		{
			s[a].you[b]++;
			s[b].you[a]++;
		}
	}
	for(int i=1;i<n;i++)
	{
		for(auto&c:s[i].you)
		{
			for(auto&d:s[c.first].you)
			{
				s[i].you[d.first]++;
			}
		}
	}
	for(int i=0;i<k;i++)
	{
		int a1,a2;
		cin>>a1>>a2;
		if(s[a1].you[a2]>0&&s[a1].di[a2]==0
			&&s[a2].you[a1]>0&&s[a2].di[a1]==0)
		{
			cout<<"No problem"<<endl;
		}else if(s[a1].you[a2]==0&&s[a1].di[a2]==0
			&&s[a2].you[a1]==0&&s[a2].di[a1]==0)
		{
			cout<<"OK"<<endl;
		}else if(s[a1].you[a2]==0&&s[a1].di[a2]>0
			&&s[a2].you[a1]==0&&s[a2].di[a1]>0)
		{
			cout<<"No way"<<endl;
		}else
		{
			cout<<"OK but..."<<endl;
		}
	}
	return 0;
}

7-7 估值一亿的AI核心代码

字符串随笔
https://www.cnblogs.com/miao-jc/p/18056399

点击查看题目
本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:

· 无论用户说什么,首先把对方说的话在一行中原样打印出来;
· 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,
把行首尾的空格全部删掉,把标点符号前面的空格删掉;
· 把原文中所有大写英文字母变成小写,除了 I;
· 把原文中所有独立的 can you、could you 对应地换成 I can、I could
—— 这里“独立”是指被空格或标点符号分隔开的单词;
· 把原文中所有独立的 I 和 me 换成 you;
· 把原文中所有的问号 ? 换成惊叹号 !;
· 在一行中输出替换后的句子作为 AI 的回答。

**输入格式:**
输入首先在第一行给出不超过 10 的正整数 N,
随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,
对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。

**输出格式:**
按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。

输入样例:
6
Hello ?
 Good to chat   with you
can   you speak Chinese?
Really?
Could you show me 5
What Is this prime? I,don 't know
输出样例:
Hello ?
AI: hello!
 Good to chat   with you
AI: good to chat with you
can   you speak Chinese?
AI: I can speak chinese!
Really?
AI: really!
Could you show me 5
AI: I could show you 5
What Is this prime? I,don 't know
AI: what Is this prime! you,don't know

解题代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);
	int n;
	cin>>n;
	string s;
	getline(cin,s);
	while(n--)
	{
		getline(cin,s);//读入一句话。
		cout << s << "\nAI: ";//原封不动的输出并加上开头。
		//把行首尾的空格全删掉。
		while(s.back()==' ')
			s.pop_back();
		reverse(s.begin(),s.end());
		while(s.back()==' ')
			s.pop_back();
		reverse(s.begin(),s.end());
		string ans;
		int cnt=0;//记录一句话中某个单词的长度。
		for(auto& c:s){
			if(c==' ')//如果当前不是字符。
			{
				cnt++;
			}else if(isalpha(c)||isdigit(c))//判断是否为字母或数字。
			{
				if(cnt)//如果这个字符是空格后的第一个字符。那就先在语句上加一个空格。
					ans+=' ';
				if(isupper(c)&&c!='I')//如果是大写字母并且不等于'I'就将其转化为小写字母
					c-='A'-'a';
				ans+=c;//将改过的字符加入新的语句中。
				cnt=0;//重新等待空格的到来。
			}else{
				if(c=='?')//如果是符号'?'就转化为'!'
					c='!';
				ans+=c;
				cnt=0;//重新等待空格的到来。
			}
		}
		//在主函数内部设立函数。
		auto f=[&](const string &k,const string&v)
		{
			int now=-1;
			while((now=ans.find(k,now+1))!=ans.npos)//在字符串ans中查找关键字k的位置,并更新now的值。
			{
				int ok=0;
				//判断边界条件,如果字符串前后不是数字或字符(是空格或标点)就让ok达到替换条件。
				if(now-1<0||(!isalnum(ans[now-1])&&!isdigit(ans[now-1])))
				{
					ok++;
				}
				if(now+k.size()>=ans.size()||(!isalpha(ans[now+k.size()])&&!isdigit(ans[now+k.size()])))
				{
					ok++;
				}
				//字符串替换。
				if(ok==2)
				{
					ans.erase(now,k.size());
					ans.insert(now,v);
				}
			}
		};
		f("can you","IS can");//①//将替换样例中的I替换为IS可以避免进行③操作时将I再换成you
		f("could you","IS could");//②
		f("I","you");//③
		f("me","you");//④
		
		for(int i=0;i<ans.size();i++)
		{
			cout<<ans[i];
			//设立了I的输出条件。
			if(ans[i]=='I'&&i+1<ans.size()&&ans[i+1]=='S')
			{
				i++;
			}
		}
		cout<<'\n';
	}
}

SMU 2024 spring 天梯赛3(补题)

7-8 连续因子

点击查看题目
一个正整数 N 的因子中可能存在若干连续的数字。
例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。
给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。

输入格式:
输入在一行中给出一个正整数 N(1<N<2^31)。

输出格式:
首先在第 1 行输出最长连续因子的个数;
然后在第 2 行中按 因子1*因子2*……*因子k 的格式输出最小的连续因子序列,
其中因子按递增顺序输出,1 不算在内。

输入样例:
630

输出样例:
3
5*6*7

这个题。。。要求的是什么啊,是这个啊:题目的逻辑是先把N拆成几个因子,再在这几个因子里找连续,而不是直接找到所有因子再找连续

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1000];
int main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	int n;
	cin>>n;
	int i=0,j=0,sum=0,num=0,temp=0,qidian=0,longqidian=0;
	int x=sqrt(n);
	//最终形式要成为n=x1*x2*x3*x4*x5....xm。
	//例如:如果n是625的话,如果下面的循环到达25了,就不必在进行26了。
	//因为因子的相乘是递增的,如果一个数的平方到达了n,那么和下一个数的再乘积一定会超过n。
	//所以只用判到sqrt(n)就好。
	for(int i=2;i<=x;i++)
	{
		num=0;
		sum=n;
		qidian=i;
		for(j=i;sum%j==0&&sum!=0;j++)
		{
			sum/=j;
			num++;
		}
		if(num>temp)
		{
			temp=num;
			longqidian=qidian;
		}
	}
	//如果n为质数的话就会用到这个条件。
	if(temp==0)
	{
		cout<<"1"<<endl<<n<<endl;
	}else
	{
		cout<<temp<<endl;
		i=longqidian;
		while(i<longqidian+temp)
		{
			if(i!=longqidian)
			{
				cout<<"*";
			}
			cout<<i;
			i++;
		}
	}
	return 0;
}

7-9 哈利·波特的考试
Dijkstra算法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxint 2147483647
typedef struct 
{
	int arcs[102][102];
	int vexnum,arcnum;
}aaa;

int s[102];
int d[102];
int path[102];
int n,i,u,j,m,v,min0,w,a,b,c,min1=999999,max1=-991111,p=0;
void djstela(aaa g,int v0)
{
	n=g.vexnum;
	for(v=0;v<n;v++)
	{
		s[v]=0;
		d[v]=g.arcs[v0][v];
		if(d[v]<maxint)
			path[v]=v0;
		else
			path[v]=-1;
	}
	s[v0]=1;
	d[v0]=0;
	for(i=1;i<n;i++)
	{
		min0=maxint;
		for(w=0;w<n;w++)
		{
			if(!s[w]&&d[w]<min0)
			{
				min0=d[w];
				v=w;
			}
		}
		s[v]=1;
		for(w=0;w<n;w++)
		{
			if(!s[w]&&(d[v]+g.arcs[v][w]<d[w]))
			{
				d[w]=d[v]+g.arcs[v][w];
				path[w]=v;
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	aaa g;
	memset(s,0,sizeof(s));
	memset(d,0x3f3f3f3f,sizeof(d));
	memset(g.arcs,0x3f3f3f3f,sizeof(g.arcs));
	cin>>g.vexnum>>m;
	for(i=0;i<m;i++)
	{
		cin>>a>>b>>c;
		g.arcs[a-1][b-1]=c;
		g.arcs[b-1][a-1]=c;
	}
	for(u=0;u<g.vexnum;u++)
	{
		max1=-9999999;
		djstela(g,u);
		for(j=0;j<g.vexnum;j++)
		{
			if(d[j]>max1)
			{
				max1=d[j];
			}	
		}
		if(max1<min1)
		{
			min1=max1;
			p=u+1;
		}
	}
	if(p==0)
	{
		cout<<"0";
	}else
	{
		cout<<p<<" "<<min1<<endl;
	}
	return 0;
}

7-10 列车厢调度 (•̀ᴗ•́)و ̑̑

点击查看错误代码
//设置了一个栈3,来模拟第三铁道,存在段错误和数组答案错误。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
stack<char>s3;
int main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	string ss1,ss2;
	cin>>ss1>>ss2;
	int p1=0,p2=0;
	while(p1!=ss1.size()||!s3.empty())
	{
		while(ss1[p1]==ss2[p2])
		{
			p1++;
			p2++;
		}	
		while(!s3.empty())
		{
			if(s3.top()==ss2[p2])
			{
				s3.pop();
				p2++;
			}else
			{
				break;
			}
		}
		while(ss1[p1]!=ss2[p2])
		{
			s3.push(ss1[p1]);
			p1++;
			if(p1>=ss1.size())
				break;
		}
		if(p2==ss2.size())
			break;
		if(s3.top()!=ss2[p2]&&ss1[p1]!=ss2[p2])
		{
			break;
		}
	}
	if(p2!=ss2.size())
	{
		cout<<"Are you kidding me?"<<endl;
	}else
	{
		int p1=0,p2=0;
		while(p1!=ss1.size()||!s3.empty())
		{
			while(ss1[p1]==ss2[p2])
			{
				p1++;
				p2++;
				cout<<"1->2"<<endl;
			}	
			while(!s3.empty())
			{
				if(s3.top()==ss2[p2])
				{
					cout<<"3->2"<<endl;
					s3.pop();
					p2++;
				}else
				{
					break;
				}
			}
			while(ss1[p1]!=ss2[p2])
			{
				cout<<"1->3"<<endl;
				s3.push(ss1[p1]);
				p1++;
				if(p1>=ss1.size())
					break;
			}
			if(p2==ss2.size())
				break;
			if(s3.top()!=ss2[p2]&&ss1[p1]!=ss2[p2])
			{
				break;
			}
		}
	}
	return 0;
}

正确代码:
1-》1->2;
2-》1->3;
3-》3->2;
先把s1和s2两个栈填充好(逆序)(先进后出),由于能用1->2完成,就不用1->3,3->2完成,首先,如果s1的顶和s2的顶相同,那么两个栈顶分别弹出,记作过程1,如果不行,才进行过程2,即从s3里面找,如果1也空了,s2有没被排空,s3的栈顶又不合要求,那么就无法完成操作。全不是,就从s1中抽元素填入s3。在s2被排空之前,重复进行操作。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	//ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	string a,b;
	cin>>a>>b;
	stack<char>s1,s2,s3;
	vector<int>way;
	int len1=a.size(),len2=b.size();
	int i;
	for(i=len1-1;i>=0;i--)
	{
		s1.push(a[i]);
	}
	for(i=len2-1;i>=0;i--)
	{
		s2.push(b[i]);
	}
	bool flag=true;
	while(!s2.empty())
	{
		if(!s1.empty()&&s1.top()==s2.top())
		{
			s1.pop();
			s2.pop();
			way.push_back(1);
		}
		else if(!s3.empty()&&s3.top()==s2.top())
		{
			s3.pop();
			s2.pop();
			way.push_back(3);
		}else if(s1.empty()&&!s2.empty()&&s3.top()!=s2.top())
		{
			flag=false;
			break;
		}else
		{
			s3.push(s1.top());
			s1.pop();
			way.push_back(2);
		}
	}
	if(!flag)
	{
		cout<<"Are you kidding me?\n";
	}
	else
	{
		int count=way.size();
		for(i=0;i<count;i++)
		{
			if(way[i]==1)
			{
				cout<<"1->2\n";
			}
			else if(way[i]==2){
				cout<<"1->3\n";
			}
			else
				cout<<"3->2\n";
		}
	}
	return 0;
}

标签:p2,2024.3,int,s2,31,long,s3,补题,&&
From: https://www.cnblogs.com/miao-jc/p/18099157

相关文章

  • 3.31
    所花时间:5小时代码量:154博客篇:1地铁起点到终点的最短路径查询:使用广度优先遍历,当要访问该站点时先储存在队列,最后出队形式访问每次访问传入数据:name:站点名;now:之前访问的站点字符串总和;nowline:当前站点的线路;ed:要到达的站点名称;i:当前经过站数以及字符串的数组下标;s:当前......
  • 3.31 联考
    3.31补题A\(5pts\)\(n=2\)时,\(\fracn2=1\),即为nim游戏。\(30pts\)对于\((a_1,a_2,a_3,a_4,a_5,a_6)\)这样的六元组,至多有\(10^6\)个。记忆化搜索他们的SG值即可。可能需要若干剪枝,因为复杂度其实是\(10^6\times6^3\)的。\(100pts\)首先观察样例2,合理猜测......
  • SUM-ACM,3月24-3-31周报
    两场天梯赛和一场atcoder。主要错误知识点在于字符串的处理和并查集的掌握不够,不懂灵活运用。第一场pta天梯赛7-56翻了一道字符串的题,我只拿了14分。我不熟悉一个点,f(i,0,s.length())是有问题的,在replace后,s.length()会改变,这个时候replace不是一个好的选择。我们只需要输......
  • CodeTonRound8-BC1C2补题
    B-BessieandMEX思路:顺,逆填都可以.见代码注释voidsolve(){//补B--不用str.find来维护,这个是o(n)的。用set的count()orfind()来维护,这两个都是o(logn)的intn;cin>>n;////顺着填:填的数字=MEX.find('0')-aior填了MEX[MEX.find('0')]='1',之后MEX.f......
  • 3.25-3.31
    天梯赛2:7-12这是二叉搜索树吗?在满足题意的前提下从前后分别往中间走模拟二叉树的建立即可。///l、//(゚、。7//l、~ヽ//じしf_,)ノ//不要放弃!猫猫会为你加油!#include<bits/stdc++.h>#defineendl'\n'#defineintlonglongusingnamespacestd;constint......
  • 回答问题2024-3-31【cadical的编译与求解格式】
    cadical的编译与求解格式调用 你好!我用的cadical求解器不需要安装。直接在编译环境下调试运行。1.在原作者主页(https://fmv.jku.at/software/index.html)下载开源程序:cadical-sc2020-45029f8.tar.xz 2解压放置pc电脑一个目录下,如D盘根目录.D:\cadical-sc2020-4......
  • SMU Winter 2024 div2 ptlks的周报Week 7(3.25-3.31)
    哈夫曼编码对出现频率大的字符赋予较短的编码,对出现频率小的字符赋予较长的编码。哈夫曼树的建树过程为,每次选取最小和次小的根节点,将它们之和作为它们的根节点,左子节点为小点,右子节点为次小点,直至仅剩一棵树。一棵哈夫曼树,左子树为0,右子树为1,以根节点到叶子结点的路径作为每个叶......
  • 20240331_搜索练习
    目录P3206DungeonMasterP3207LakeCountingP3208TheCastleP896仙岛求药P429【基础】走迷宫P2465迷宫问题P952【入门】算24点P3206DungeonMaster这题是一个三维迷宫,其中用‘.’表示空地,‘#’表示障碍物,‘S’表示起点,‘E’表示终点,求从起点到终点的最小移动次......
  • 拌合楼管理软件开发(十三) 对接耀华XK3190-A9地磅(实战篇)
    前言:实战开整    目前而言对于整个拌合楼管理软件开发,因为公司对这个项目还处于讨论中,包括个人对其中的商业逻辑也存在一些质疑,都是在做一些技术上的储备.很早就写好了串口与地磅对接获取代码,也大概知道真个逻辑,这次刚好跟库区沟通,远程连接到磅房电脑,开始实......
  • 3.25-3.31周报
    天梯赛27-10红色警报这道题的题意要注意是删去一个城市后增加了多少个区域,而不是有多少个城市变成了单独的点,赛时理解错了题意,用set做会有点有问题。其实很简单,就是bfs搜一下有多少个联通块,每次删除把被删的点打个标记,每次联通块的个数和上一次的比较一下,只要增加就是改变了连......