思路:一個K位的數的每一位的和最大也就是K*9,遍歷1~K*9,若有一個數滿足dr(sum) = d,則說明K位的數中有滿足條件的數,且和爲sum,則任意一個和爲sum的K位數都滿足條件,任意輸出一個即可。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
//typedef __int64 int64;
typedef long long ll;
#define M 100005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007
int ans[1005];
int Cal(int k)
{
int ret = k;
while (ret >= 10)
{
while (k)
{
ret = 0;
ret += k%10;
k /= 10;
}
k = ret;
}
return ret;
}
int main()
{
int k , d;
scanf("%d%d",&k,&d);
if (d == 0)
{
if (k == 1)printf("0\n");
else printf("No solution\n");
return 0;
}
int i , n = k*9;
for (i = 1 ; i <= n ; i++)
{
int dr = Cal(i);
if (dr == d)
{
while (dr > 9)printf("9"),dr-=9,k--;
if (k > 0)printf("%d",dr),k--;
int j;
for (j = 0 ; j < k ; j++)printf("0");
printf("\n");
return 0;
}
}
printf("No solution\n");
return 0;
}
B:Vasya and Public Transport
思路:可能的結果爲:買一張所有都能坐的票花c4,或者 bus和trolley分別去買,分別買就又分爲(對bus來說)買一張能坐全部bus的票花c3,或者對於每一個bus單獨買票,對一個bus單獨買又分爲買多張單程票和買一張能一直坐的票。對trolley分析是一樣的,答案就是所有這些可能結果的最小值。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
//typedef __int64 int64;
typedef long long ll;
#define M 100005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007
int main()
{
int c1,c2,c3,c4;
int n,m;
int a[1005],b[1005];
scanf("%d%d%d%d",&c1,&c2,&c3,&c4);
scanf("%d%d",&n,&m);
int i , az = 0 , bz = 0;
for (i = 0 ; i < n ; i++)
{
scanf("%d",a+i);
if (a[i] != 0)az = 1;
}
for (i = 0 ; i < m ; i++)
{
scanf("%d",b+i);
if (b[i]!=0)bz = 1;
}
int ret1 = 0 , ret2 = 0;
for (i = 0 ; i < n ; i++)ret1 += min(a[i]*c1,c2);
for (i = 0 ; i < m ; i++)ret2 += min(b[i]*c1,c2);
ret1 = min(ret1,c3);
ret2 = min(ret2,c3);
printf("%d\n",min(c4,ret1+ret2));
return 0;
}
C:Vasya and Robot
思路:逆向抓取,若只有一個物品,機器人用左手和右手抓取分別爲lsum和rsum,然後在這個物品的左右兩邊分別放一個物品,則對這兩個物品抓取分別分爲用左手或者用右手:
1.先最左邊用左手抓,最右邊也用左手,則所有的物品都必須用左手抓。
2.先最左邊用左手抓,最右邊用右手,則答案爲w[z]*l+w[y]*r+min(lsum,rsum+qr)。z,y爲最左和最右
3.先最右邊用右手抓,最左邊也用右手,則所有的物品都必須用右手手抓。
4.先最右邊用右手抓,最左邊用左手,則答案爲w[y]*r+w[z]*l+min(lsum+ql,rsum)。
物品總個數爲奇數初始爲一個物品,爲偶數初始爲2個物品、
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
//typedef __int64 int64;
typedef long long ll;
#define M 100005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007
int n , l , r , ql , qr;
int w[M] , sum[M];
int main()
{
int i;
scanf("%d%d%d%d%d",&n,&l,&r,&ql,&qr);
for (sum[0] = 0 , i = 1 ; i <= n ; i++)scanf("%d",w+i),sum[i]=sum[i-1]+w[i];
int z , y , lsum = 0 , rsum = 0;
if (n&1)
{
z = y = n/2+1;
lsum = w[z]*l;
rsum = w[y]*r;
}
else
{
z = n/2;
y = n/2+1;
lsum = min(w[z]*l+w[z+1]*l+ql,w[z]*l+w[z+1]*r);
rsum = min(w[y]*r+w[y-1]*r+qr,w[y]*r+w[y-1]*l);
}
z--,y++;
while (z >= 1)
{
int lt , rt;
int temp = (sum[y]-sum[z-1]);
lt = min(temp*l+ql*(y-z),w[z]*l+w[y]*r+min(lsum,rsum+qr));
rt = min(temp*r+qr*(y-z),w[y]*r+w[z]*l+min(lsum+ql,rsum));
lsum = lt;
rsum = rt;
z--,y++;
}
printf("%d\n",min(lsum,rsum));
return 0;
}