加密语句(模拟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;
}