2022“杭电杯”中国大学生算法设计超级联赛(2)(2,7,9,12)

本文探讨了如何在Python中使用(...,...)模拟C++中的std::make_tuple,涉及字符串替换、时间复杂性分析及特定算法应用。作者分享了解题过程,从背包方法到最终采用搜索策略解决问题。
摘要由CSDN通过智能技术生成

第2题

Kayzin的存储库在C++有很多代码,但Aba aba只能理解Python代码。所以Aba aba打电话给你寻求帮助。你唯一应该做的就是在Python中使用(...)来匹配C++中的std::make_tuple(...)。

第一行有一个整数T表明T测试用例。在每种情况下:第一行有字符串s,表示C++代码。C++代码仅包含 std::make_tuple、“(”、“)”、“、”“和整数,不带空格。1≤T≤100,长度s不超过 1000。

一道简单的字符串替换,但因为缺少考虑,所以先wa了两发,比较难受。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin>>t;

	while(t--){
		string s;
		cin>>s;
		for(int i=0;i<s.length();i++){
			if(s[i]=='s'||s[i]=='t'||s[i]=='d'||s[i]==':'||s[i]=='m'||s[i]=='a'||s[i]=='k'||s[i]=='e'||s[i]=='_'||s[i]=='u'||s[i]=='p'||s[i]=='l') continue;
			else cout<<s[i];
		}
	 cout<<endl;
	}
 }  

第7题

一个有趣的例外是Spanner中的Google的TrueTime API,它明确报告本地时钟上的置信区间。当您询问当前时间时,您将获得两个值:[最早,最晚],它们是最早的可能和最晚的时间戳。根据其不确定性计算,时钟知道实际当前时间在该间隔内的某个位置。间隔的宽度取决于自本地石英时钟上次与更精确的时钟源同步以来已经过了多长时间。

TL;DR:Spanner 以这种方式跨数据中心实现快照隔离。它使用 TrueTime API 报告的时钟置信区间,并基于以下观察结果:如果您有两个置信区间,每个置信区间由最早和最晚的可能时间戳 (A=[A_{最早},A_{latest}],B=[B_{最早},B_{最新}]A=[Aearliest​,Alatest​],B=[Bearliest​,Blatest​]),并且这两个区间不重叠(即A_{最早} < A_{最新} < B_{最早} < B_{最新}一个earliest​<一个latest​<Bearliest​<Blatest​),那么B肯定是在A之后发生的——毫无疑问。只有当区间重叠时,我们才不确定A和B以哪个顺序发生。

现在我们使用Spanner作为解决方案,有数百万人抢购杂货,每个人都被赋予了时钟的置信区间。服务器按时间顺序执行每个请求,并在间隔重叠时终止。问题是,在服务员终止之前,有多少人可以获得食物。

其实也算是一道签到题,但题目的阅读量很大,所以最开始我们跳过了这道题,最后看懂题意就是简单的数组处理就可以了。

#include<bits/stdc++.h>
using namespace std;
int t,n,l,r,x,y,ans;
bool flag;
int main(){
	scanf("%d",&t);
	for (int i=1;i<=t;i++){
		scanf("%d",&n);
		flag=true;
		ans=0;
		for (int j=1;j<=n;j++){
			if (j==1){
				scanf("%d %d",&x,&y);
				continue;
			}
			scanf("%d %d",&l,&r);
			if (flag==false)
				continue;
			if (y>=l){
				flag=false;
				continue;
			}
			
			ans++;
		}
		if (flag)
			ans++;
		printf("%d\n",ans);
	}
	return 0;
}

但很遗憾wa了,耽误队伍罚时了,好在大佬马上就用2维队列AC了,还是得多学一下用队列和栈解题的方法,一直会被忽略。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef pair<int,int> PII;
int l[N],r[N];
int main()
{
	int t;
	cin>>t;
	while(t--){
		int n;
		scanf("%d",&n);
		vector<PII> q; 
		for(int i=1;i<=n;i++){
			scanf("%d%d",&l[i],&r[i]);
			q.push_back({l[i],r[i]});
		}
		sort(q.begin(),q.end());
		int ll=-1,rr=-1;
		vector<PII> p;
        bool flag=true;
		for(auto x:q){
			if(x.first>rr){
				if(rr!=-1){
					p.push_back({ll,rr});
				}
				ll=x.first,rr=x.second;
			}
			else {flag=false;break;}
		}
        if(flag)p.push_back({ll,rr});
		printf("%d\n",p.size());
	}
}

第12题

Kayzin计划购买一艘豪华游轮,这将花费N个硬币。但是凯津没有足够的硬币,所以凯津决定开始保存硬币。Kayzin每天都会向他的存钱罐中放入7,31或365个硬币。现在,Kayzin想知道至少需要多少天才能“确切地”(不多也不少)凑钱购买豪华游轮。如果Kayzin不能“完全”凑钱购买豪华游轮,请打印-1。

最开始我们用背包做,但因为连样例都过不了就放弃了。后面发现数据量不大,所以我们就可以用搜索的方法解题,就是先对365的次数,31的次数,7的次数,通过减少大的数字出现的次数,提高后面的次数,看有没有符合的。所以就可以很快解决。

#include<bits/stdc++.h>
using namespace std;
int t;
long long int s;
long long int slove(long long int x)
{
	long long ans=0,temp,i,j,k;
    for (i=x/365;i>=0;i--){
    	for (j=(x-i*365)/31;j>=0;j--){
    		k=(x-i*365-j*31)%7;
    		if (k==0){
    			//cout<<i<<"  "<<j<<"  "<<"rggf";
    			return (i+j+(x-i*365-j*31)/7);
    	    }
		}
	}
	return -1;
} 
int main()
{
  	cin>>t;
  	for (int i=1;i<=t;i++){
  		cin>>s;
  		cout<<slove(s)<<endl;
	}
	return 0;
} 

补题时间

第9题

CX是一家慕课公司的程序员。几天前,他将用户数据泄露归咎于此。因此,他必须开发一种加密算法,这是他的天才想法。

首先,协议指定了素模MM,然后服务器生成私钥PP,并向客户端发送公钥QQ.这里Q = P ^ {-1},P mod MQ=P−1,P×Q≡1modM.

加密公式:encrypted_{data} = raw_{data}  P mod Menpteddata​=rawdata​×PmodM

解密公式:raw_{data} = encrypted_{data}  Q mod Mrawdata​=enpteddata​×QmodM

然而,作为数论的大师,你要解密它,这确实是有道理的。您截获了有关P, Q, encrypted_{data}PQenpteddata​和M保持未知。如果可以解密,请输出raw_{数据}rawdata​,否则,对CX说“shuanQ”。

通过数论可以轻松发现,该题是和M相关的,所以我们就一直在尝试求出M,但不知道为什么一直在wa。

#include<bits/stdc++.h>
using namespace std;
long long int t,p,q,en,ra,m,ma,s,h,x,y;
bool flag;
bool judge(long long int n)
{
	for (long long int i=2;i<=sqrt(n);i++){
        if(n%i==0){
           return false;
        }
    }
    return true;   
}
int main()
{
	cin>>t;
	for (int i=1;i<=t;i++){
		cin>>p>>q>>en;
		ma=max(p,q);
		h=p*q-1;
		flag=false;
		s=(sqrt(p*q-1))+1;
		for (long long int j=2;j<=s;j++){
			if (h%j==0){
				x=j;y=h/j;
				if (x>ma && judge(x)){
					m=x;
					ra=(en*q)%m;
					if (en==(ra*p)%m){
						cout<<ra<<endl;
						flag=true;
						break; 
					}
				}
				if (y>ma && judge(y)){
					m=y;
					ra=(en*q)%m;
					if (en==(ra*p)%m){
						cout<<ra<<endl;
						flag=true;
						break; 
					}
				}
			}	 
		}
		if (flag==false)
				cout<<"shuanQ"<<endl;
	}
	return 0;
}

后面看题解也不是很懂为什么自己写的有问题,不过看其他大佬的代码也就搞懂了,还是求M。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值