A. 个数就不说了,第二个值 有多余的凑起来能再买一个就把还需要钱少的输出否则为0
//567 A
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll x,y,z;
cin>>x>>y>>z;
if(x%z+y%z<z){
cout<<x/z+y/z<<" ";
cout<<0<<"\n";
}else{
ll ans = (x+y)/z;
x = z-x%z;
y = z-y%z;
cout<<ans<<" "<<min(x,y);
}
return 0;
}
B.字符串加法,分割长度为n的数为两部分,求两部分之和最小值。不允许有前导0
比较枚举几次就行,我在出结果后( strlen(num3)!=0 )还枚举了四次,以防万一
//B
#include <bits/stdc++.h>
#define ll long long
using namespace std;
char s[100005];
char num1[100005], num2[100005], num3[100005];
int L, M;
int mark;
void add(char a[], char b[], char c[]) {
int len1 = strlen(a);
int len2 = strlen(b);
int i, j;
int l = 0;
L = 0;
int temp;
for(i = 0; i < len1/2; i++) {
temp = a[i];
a[i] = a[len1-1-i];
a[len1-1-i] = temp;
}
for(i = 0; i < len2/2; i++) {
temp = b[i];
b[i] = b[len2-1-i];
b[len2-1-i] = temp;
}
for(i = 0; i < len1 && i < len2; i++) {
M = (a[i] - '0' + b[i] - '0' + L) % 10;
L = (a[i] - '0' + b[i] - '0' + L) / 10;
c[i] = M + '0';
}
if(i < len1) {
for( ; i < len1; i++) {
M = (a[i] - '0' + L) % 10;
L = (a[i] - '0' + L) / 10;
c[i] = M + '0';
}
}
if(i < len2) {
for( ; i < len2; i++) {
M = (b[i] - '0' + L) % 10;
L = (b[i] - '0' + L) / 10;
c[i] = M + '0';
}
}
while(L) {
c[i++] = L + '0';
L /= 10;
}
mark = i-1;
}
int judge(char a[],char b[]) {
if(strlen(a)>strlen(b))return -1;
if(strlen(a)<strlen(b))return 1;
for(int i=strlen(a)-1; i>=0; i--) {
if(a[i]>b[i]) {
return -1;
} else if(a[i]<b[i]) {
return 1;
}
}
return 0;
}
int main() {
int n,tp;
int ans = 0,ans1=0;
cin>>n;
cin>>s;
tp = n/2;
int flag = 0,ind=1;
int nn=0;
for(int j=0; j<n; j++) {
if(tp+j<n&&s[tp+j]!='0') {
for(int i=0; i<tp+j; i++) {
num1[i] = s[i];
}
num1[tp+j] = '\0';
for(int i=tp+j; i<n; i++) {
num2[i-(tp+j)] = s[i];
}
num2[n] = '\0';
add(num1,num2,num2);
if(strlen(num3)==0)strcpy(num3,num2);
else {
nn++;
if(judge(num3,num2)<0) {
strcpy(num3,num2);
}
}
memset(num2,0,sizeof(num2));
memset(num1,0,sizeof(num1));
}
if(tp-j>0&&s[tp-j]!='0'){
for(int i=0; i<tp-j; i++) {
num1[i] = s[i];
}
num1[tp-j] = '\0';
for(int i=tp-j; i<n; i++) {
num2[i-(tp-j)] = s[i];
}
num2[n] = '\0';
add(num1,num2,num2);
if(strlen(num3)==0)strcpy(num3,num2);
else {
nn++;
if(judge(num3,num2)<0) {
strcpy(num3,num2);
}
}
memset(num2,0,sizeof(num2));
memset(num1,0,sizeof(num1));
}
if(nn>=4){
break;
}
}
for(int i=strlen(num3)-1;i>=0;i--){
printf("%c",num3[i]);
}
return 0;
}
C.
题意:给n行m列矩阵,问有多少符合规则的矩形
规则:包含三种颜色,分上中下三部分,两两相邻部分颜色不同长度宽度相同
题解:数据1000,动规
d[ i ][ j ]表示s[ i ][ j ] 能往下延伸(颜色相同)最长的长度,对每个点算出以该点为顶点的符合规则的矩形数
对每一行维护变量 k,第 i 一列和第 i - 1列符合则 k++,否则 k = 1.如果连行的条件都不满足 那么k = 0
每次算出k, ans+=k;
//C
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1010;
int n,m,d[maxn][maxn];ll ans;
char s[maxn][maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
for(int i=n;i>=1;i--){
for(int j=1;j<=m;j++){
if(s[i][j]==s[i+1][j]){
d[i][j] = d[i+1][j]+1;
}else d[i][j] = 1;
}
}
for(int i=1;i<=n;i++){
for(int j=1,k=0;j<=m;j++){
int h = d[i][j];
if(3*h+i-1<=n&&d[i+h][j]==h&&d[i+2*h][j]>=h&&s[i][j]!=s[i+h][j]&&s[i+2*h][j]!=s[i+h][j]){
if(k&&s[i][j]==s[i][j-1]&&d[i][j-1]==h&&s[i+h][j]==s[i+h][j-1]&&d[i+h][j-1]==h&&s[i+2*h][j]==s[i+2*h][j-1]&&d[i+2*h][j-1]>=h){
k++;
}else k = 1;
}else k = 0 ;
ans+=k;
}
}
cout<<ans<<endl;
return 0;
}