暑期 集训1期5

加密语句(模拟map)

简单的替换型密码是很弱的,它通过将每个字母替换成另外一个字母来加密 一个字母组成的信息。考虑下面的替换型密码描述:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
NOPQRSTUVWXYZABCDEFGHIJKLM
这样的描述表示当输入中出现“A”的时候,输出中应该出现的是“N”。同
理,每个“B”都变成“O”,以此类推,一直到“Z”都变成“M”。这个特殊的替
换型密码的例子被称为“rot13”(旋转 13——rotate-13 的简称),有一个有趣
的特性:它是自解密的。将信息再加密一次就会得到原始的信息。
这样的密码中,单词“CAT”就会成为“PNG”。而句子:
NOW IS THE TIME FOR ALL GOOD PEOPLE TO PROGRAM WELL.
就成了:
ABJ VF GUR GVZR SBE NYY TBBQ CRBCYR GB CEBTENZ JRYY.
注意所有的空格、标点符号以至于任何不在字符集“A”-“Z”中的字符都
不变。
请你写一个程序来实现替换型密码。

用map记录每个英文字母所对应的密码,然后对应的输出

#include<bits/stdc++.h>
using namespace std;
map<char,char>q;
string s;
int main()
{
    
    
    getline(cin,s);
    for(int i=0;i<s.size();i++)q['A'+i]=s[i];
 
    getline(cin,s);
    for(int i=0;i<s.size();i++)
    {
    
    
        if(s[i]>='A'&&s[i]<='Z')
        cout<<q[s[i]];
        else cout<<s[i];
    }
    return 0;
}


T2 阿卡的大数(贪心+高精)

在这里插入图片描述
考虑贪心,题目要求分开两数和最大那么,先将位数从大到小进行排序,排完之后,如果个位不是0,那么取出个位然后相加肯定是最大的,如果个位是0,找到第一个!0位数,然后相加

#include<bits/stdc++.h>
using namespace std;
int n;
int a[15000];
int s1[15000],s2[15000],tep1,tep2;
int q[15000],p[15000],ans[15000];
int gg;
int main()
{
    
    
    cin>>n;
    string s;cin>>s;
    for(int i=1;i<=n;i++)a[i]=s[i-1]-'0';
     
    sort(a+1,a+1+n);
    if(a[1]!=0)
    {
    
    
        for(int i=2;i<=n;i++)q[i-1]=a[i];//取个位
        p[1]=a[1];
    }
    else
    {
    
    
    int tp=1;
    while(!a[tp])tp++;
    int tep=1;
    for(int i=1;i<=n;i++)if(i!=tp)q[tep]=a[i],tep++;
    p[1]=a[tp];//找到第一个!0
    }
 
    for(int i=1;i<=n+1;i++)//高精加
    {
    
    
        ans[i]+=q[i]+p[i];
     
        if(ans[i]>9)
        {
    
    
            ans[i]-=10;
            ans[i+1]++;
        }
    }
    int tep3=n+1;
     
    while(!ans[tep3]&&tep3>1)tep3--;
    for(int i=tep3;i>=1;i--)
    cout<<ans[i];
    return 0;
}


T3烤乐滋排队(DP)在这里插入图片描述

70pts O(n*n)
设f[i]表示以i元素为结尾的方案数,第二次循环j从1枚举到i如果i是j的倍数,可以考虑转移
100pts O(nlogn)
考虑将所有重复的数给合并在一起,去更新他们倍数的dp值,要成x的个数

#include<bits/stdc++.h>
#define mo 998244353
using namespace std;
long long dp[150000],n,a[150000];
map<int ,int>q;
int main()
{
    
    
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    
    
     cin>>a[i];   
     q[a[i]]++;//记录个数
     dp[i]=1;
    }
    for(int i=1;i<=n;i++)
    {
    
    
        dp[i]=(dp[i]*q[i])%mo;
        for(int j=i*2;j<=n;j+=i)//转移倍数dp值
        dp[j]+=dp[i],dp[j]%=mo;
    }
    long long ans=0;
    for(int i=1;i<=n;i++)ans+=dp[i],ans%=mo;
    cout<<ans+1;
    return 0;
}


T4 幻想道路(最短路)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

题面都告诉你了,这是一道求最短路的题,那应该挺简单了。
就是跑两遍spfa,然后对于每一条边,结果等于min(dis(n + 1; x) + dis(n + 2; y),dis(n + 1; y) + dis(n + 2; x))+val(x,y)
1.虽然知道是无向图,一个城市到多个城市可以有很多种道路嘛。
2.记录连接幻想王国的边时,不能和邻接表产生一定关系。因为无向图连了两次,需要在读入时重开数组记录。
3.初始化的时候注意是n+2座城市。还有新来的快乐星球、黑暗星球)

#include<bits/stdc++.h>
#define maxn 150000
using namespace std;
long long dis1[maxn],dis2[maxn],vis[maxn];
int n,m,q,head[maxn],tot;
struct node1
{
    
    
	int xx;
	int yy;
	int zz;
}a[maxn];
struct node
{
    
    
	int next;
	int v;
	int w;
}edge[maxn];
void add(int x,int y,int z)
{
    
    
	tot++;
	edge[tot].next=head[x];
	edge[tot].v=y;
	edge[tot].w=z;
	head[x]=tot;
}

void spfa(int x)
{
    
      
    queue<int>q;
	q.push(x);
	vis[x]=1;
	dis1[x]=0;
	while(!q.empty())
	{
    
    
		int k=q.front();
		q.pop();
		vis[k]=0;
		for(int i=head[k];i;i=edge[i].next)
		{
    
    
			 int neww=edge[i].v;
		    if(dis1[neww]>dis1[k]+edge[i].w)
		    {
    
    
			 dis1[neww]=dis1[k]+edge[i].w;
			 if(!vis[neww])
			 {
    
    
			  q.push(neww);
			  vis[neww]=1;
			 }
		    }
		}
	}
}
void spfa2(int x)
{
    
    
	queue<int>q;
	q.push(x);
	vis[x]=1;
	dis2[x]=0;
	while(!q.empty())
	{
    
    
		int k=q.front();
		q.pop();
		vis[k]=0;
		for(int i=head[k];i;i=edge[i].next)
		{
    
    
		    int neww=edge[i].v;
            if(dis2[neww]>dis2[k]+edge[i].w)
		    {
    
    
			 dis2[neww]=dis2[k]+edge[i].w;
			 if(!vis[neww])
			 {
    
    
			  q.push(neww);
			  vis[neww]=1;
			 }
		    }
		}
	}
}
int main()
{
    
    
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++)
	{
    
    
		int x,y,z;cin>>x>>y>>z;
		a[i].xx=x;a[i].yy=y;a[i].zz=z;
		add(x,y,z);
		add(y,x,z);
	}
	for(int i=1;i<=q;i++)
	{
    
    
		int x,y,z;cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}	
	memset(vis,0,sizeof(vis));
    memset(dis1,0x3f3f3f3f,sizeof(dis1));
    memset(dis2,0x3f3f3f3f,sizeof(dis2));
	spfa(n+1);
	memset(vis,0,sizeof(vis));
	spfa2(n+2);	
	/*for(int j=1;j<=n+2;j++)
	cout<<dis1[j]<<' '<<dis2[j]<<endl;*/
	for(int i=1;i<=m;i++)
	{
    
    
//		cout<<dis1[a[i].xx]<<' '<<dis2[a[i].xx]<<' '<<dis1[a[i].yy]<<' '<<dis2[a[i].yy]<<' '<<0x3f3f3f3f <<endl; 
	if(   (   (dis1[a[i].xx]>=0x3f3f3f3f)    ||   (dis2[a[i].yy]>=0x3f3f3f3f)  )  &&   (   (dis2[a[i].xx]>=0x3f3f3f3f)    ||   (dis1[a[i].yy]>=0x3f3f3f3f)  )  ) 
	{
    
    
		cout<<"GG"<<endl;
		continue;
	  }  
	else cout<<min(dis1[a[i].xx]+dis2[a[i].yy]+a[i].zz,dis1[a[i].yy]+dis2[a[i].xx]+a[i].zz)<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yhhy666/article/details/108237548
今日推荐