找规律水题

题面
题面
我的代码tle 以肉眼可见的速度超时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<cstdio>
using namespace std;
typedef unsigned long long ll;
int main()
{
ll k,m,n;
while(~scanf("%llu%llu",&m,&n))
{
scanf("%llu",&k);
ll sum=0;
for(int i=1;i<=m;i++)
{
for(int j=i;j<=n;j++)
{
if((i+j)*2>k)
break;
// cout<<'i'<<i<<'j'<<j<<endl;
if(i==j)
sum+=(m+1-i)*(n+1-j); ///正方形算一遍
else ///长方形横着加上竖着
sum+=((m+1-i)*(n+1-j))+((n+1-i)*(m+1-j));
// cout<<"count "<<(m+1-i)*(n+1-j)<<endl;
// cout<<"count2 "<<(n+1-i)*(m+1-j)<<endl;
}
}
printf("%llun",sum);
}
return 0;
}

ac代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int main()
{
int n,m,k;
while(~scanf("%d %d %d",&n,&m,&k)){
long long sum=0,a[maxn]={0};
for( int i=1; i<=m; i++ ) a[i]=a[i-1]+m-i+1;//m-i+1表示宽度为i在m列里有几种放置情况,a[i]表示总和;
for( int j=1; j<=n; j++ ){//高从j到n;
int cnt_x=min(k/2-j,m);
if(cnt_x<0) cnt_x=0;
int cnt_y=n-j+1;//高为j在n列里情况
sum+=a[cnt_x]*cnt_y;
}
printf("%lldn",sum);
}
return 0;
}

beauty
nice