1005.
水题,唯一难点是明白题意。每次加入一个字母,判断其RP值为多少位,那么之前的余数ans就要乘几个10(为了拼接在后面),接下来对101取余,依次做完即可。
#include
using namespace std;
char s[52000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
int sum=0;
for(int i=0;s[i]!='\0';i++)
{
int x=(s[i]-'a'+1)*(s[i]-'a'+1);
int len=log10(x)+1;
while(len--) sum=sum*10;
sum+=x;
sum=sum%101;
}
printf("%d\n",sum);
}
return 0;
}
1007.
很明显我们能想到这样一个状态:dp[i]代表以第i个字母结尾能取得的最大值是多少。那么如果第j个字符串与以i结尾的原串匹配成功了,那么dp[i]=max(dp[i],dp[i-len(第j个字符串长度)]+w[i])(我字符串下标从0开始DP枚举从1开始)。考虑到有-1存在,那么我们初始化所有为-1,dp[0]=0;然后如果dp[i-len]==-1显然状态是不可到达的,所以要舍去。这个题如果完全暴力复杂度是N*LEN(X)*30,可以险过。还可以采取用字典树的方式,逆向插入。然后枚举以i结尾去查找字典树(最多30层),复杂度为N*30。
#include
using namespace std;
#define ll long long
int dp[12000];
int w[1200],lens[1200];
char s[1200][50],x[12000];
int main()
{
int n;
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
while(scanf("%d %s",&n,x)!=EOF)
{
for(int i=1; i<=n; i++)
{
scanf("%s %d",s[i],&w[i]);
}
for(int i=1;i<=n;i++)
lens[i]=strlen(s[i]);
memset(dp,-1,sizeof(dp));
dp[0]=0;
int len=strlen(x);
for(int i=1; i<=len; i++)
{
for(int j=1; j<=n; j++)
{
if(lens[j]>i) continue;
int k;
for(k=0; k
1008.
因为题目要求的是子序列,范围只有10.摆明的DFSor状压枚举。情况数也就是2^10..,找出最大值与次大值就好了。嗯由于题目数据比较水,n^2枚举子串也是可以过的。。。
#include
using namespace std;
int n,a[30];
int max1,max2;
void dfs(int pos,int sum)
{
if(pos>n)
{
if(sum>max1)
{
max2=max1;
max1=sum;
}
else if(sum>max2&&sum
1009.
题意读懂之后很容易想明白,其实就是个递推的问题。但是由于M过于大,递推问题的较大项可以采取矩阵快速幂的方式。构造矩阵的话 初始矩阵明显是一个1*n的,分别是n桶水的初始水量。转移矩阵是根据分水的情况定的。第i桶水分给了第j桶水 mat[i][j]=(i的平均分水量)。
#include
using namespace std;
#define ll long long
struct matrix
{
double mat[15][15];
};
matrix matmul(matrix a,matrix b,int n) //矩阵乘法 n阶矩阵a、b相乘对m取模
{
int i,j,k;
matrix c;
memset(c.mat,0,sizeof(c.mat));
for(i=0;i>=1;
}
return b;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
matrix a,b,ans;
memset(a.mat,0,sizeof(a.mat));
memset(b.mat,0,sizeof(b.mat));
for(int i=0;i