题目链接:Board Moves - CodeForces 1353C - Virtual Judge (vjudge.net)
题解来源:(34条消息) Codeforces 1353 C. Board Moves(规律)_Huffman_Tree_的博客-CSDN博客
思维 找规律
题意:给定N*N的正方形,每个位置上有一个价值,你可以通过走八个偏移量,每次只能走一步,求出让所有价值附加在一点上的最小步数
思路:对于所有价值我们可以全部集合到最中间的那个点上。
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int t;
cin>>t;
while(t--)
{
int x;
cin>>x;
int k=(x+1)/2-1;
int m=0,sum=0;
for(int i=k;i>=1;i--)
{
m=x*4-4;
sum+=m*i;
x-=2;
}
cout<<sum<<endl;
}
return 0;
}
题目链接:String Problem - CodeForces 33B - Virtual Judge (vjudge.net)s
题解来源:(34条消息) Codeforces 33B. String Problem(Floyd最短路)_baodream的博客-CSDN博客
Floyd
题意: 给定两个字符串,和n个操作,每次可以让一个字符变为另外一个字符且消耗价值w,问可不可以让这两个字符串变为相同的另外一个字符串,求消耗的最小价值和变成的字符串
思路:floyd求出n个字符变换的最小价值,再通过枚举给定字符串长度的大小来一次次在已经确定好的最短路字符方案里找可行方案并更新最小距离。
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e5+10,M=1,inf=0x3f3f3f3f;
int g[30][30];
char a[N],b[N],c[N];
int t;
void floyd()
{
for(int k=0;k<=25;k++)
{
for(int i=0;i<=25;i++)
{
for(int j=0;j<=25;j++)
{
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
}
int main()
{
cin>>a>>b>>t;
for(int i=0;i<30;i++)
{
for(int j=0;j<30;j++)
{
if(i==j) g[i][j]=0;
else g[i][j]=inf;
}
}
for(int i=0;i<t;i++)
{
char x,y;
int w;
cin>>x>>y>>w;
g[x-'a'][y-'a']=min(g[x-'a'][y-'a'],w);
}
floyd();
bool flag=false;
int ans=0;
if(strlen(a)!=strlen(b))
{
cout<<-1<<endl;
return 0;
}
int len=strlen(a);
for(int i=0;i<len;i++)
{
int minn=inf;
int t1=a[i]-'a';
int t2=b[i]-'a';
for(int j=0;j<=25;j++)
{
int x1=g[t1][j];
int x2=g[t2][j];
if(x1!=inf&&x2!=inf&&minn>x1+x2)
{
minn=x1+x2;
c[i]='a'+j;
}
}
if(minn==inf)
{
flag=true;
break;
}
ans+=minn;
}
if(flag)
{
cout<<-1<<endl;
return 0;
}
//c[len]='\0';
cout<<ans<<endl;
cout<<c<<endl;
return 0;
}
题目链接:chokudai - AtCoder abc211_c - Virtual Judge (vjudge.net)
题解链接: (34条消息) AtCoder Beginner Contest 211 C - chokudai_CCSU_梅子酒的博客-CSDN博客
dp
题意:给定一个字符串a="chokudai",输入一个字符串s,问有多少种方案可以让唯一顺序读出这个字符串,求所给方案
思路:遍历字符串s,每次让字符串中的字符与a中字符串比较
dp[j][i]记录的是字符串s前1~j位子序列的方案数。
在我们遍历字符串S的时候需要对每个字符匹配其是否为a中的一种,若匹配成功则状态转移方程为:dp[j][i]=dp[j-1][i-1]+dp[j][i-1]
含义为dp[j][i]=S串中之前一位匹配成功的a[1~j]的方案数(dp[j][i-1])+之前一位匹配成功的a[1~j-1]的方案数和本次这一个j字符凑成新的a[1~j]方案(dp[j-1][i-1])
同时注意需要特判的是当我们匹配的字符是第一个时即“c”字符因为之前没有字符串给其加上权值了即dp[j-1][i-1]是无效的方程需要写成dp[j][i]=dp[j][i-1]+1
二、匹配不成功就很简单了,只需要加上S串上一位的a[1~j]的值dp[j][i]=dp[j][i-1]
最后答案就是dp[8][len]了,注意要记得对1e9+7取模
二、匹配不成功就很简单了,只需要加上S串上一位的a[1~j]的值dp[j][i]=dp[j][i-1]
最后答案就是dp[8][len]了,注意要记得对1e9+7取模
string a="0chokudai"; string s; cin>>s; s='0'+s;//防止dp状态转移时越界
在0位置增加一个字符防止转态转移时数组越界
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e5+10,M=1,inf=0x3f3f3f3f,mod=1e9+7;
string s;
string a="0chokudai";
int dp[10][N];
int main()
{
cin>>s;
s="0"+s;
for(int i=1;i<=s.size();i++)
{
for(int j=1;j<=8;j++)
{
if(s[i]==a[j])
{
if(j==1) dp[j][i]=dp[j][i-1]+1;
else dp[j][i]=dp[j-1][i-1]+dp[j][i-1];
}
else
{
dp[j][i]=dp[j][i-1];
}
dp[j][i]%=mod;
}
}
cout<<dp[8][s.size()]<<endl;
return 0;
}
Two Arrays And Swaps - CodeForces 1353B - Virtual Judge (vjudge.net)
题意:给定两个数组a和b,允许交换k次,问a最大序列和
贪心 排序
当时没时间了,哎,其实很简单
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e5+10,M=1,inf=0x3f3f3f3f,mod=1e9+7;
int t;
int a[N],b[N];
int main()
{
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i];
sort(b,b+n,greater<int>());
sort(a,a+n);
for(int i=0;i<k;i++)
{
if(b[i]>a[i])
swap(a[i],b[i]);
}
int sum=0;
for(int i=0;i<n;i++) sum+=a[i];
cout<<sum<<endl;
}//
return 0;
}