第九次训练赛

A - 小A的矩阵

HDU - 1559

Sample Input

1
4 5 2 2
3 361 649 676 588
992 762 156 993 169
662 34 638 89 543
525 165 254 809 280

Sample Output

2474

思路:

可以使用DP和二维前缀数组和做

//二维前缀数组
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e3 + 5;
const int INF = 0x3f3f3f3f;
ll a[MAX][MAX];
 
int main()
{
    int t;
    int m,n,x,y;
    ll maxx;
    cin>>t;
    while(t--) {
        maxx = -INF;
        scanf("%d%d%d%d",&m,&n,&x,&y);
        for(int i = 1; i<=m; i++) {
            for(int j = 1; j<=n; j++) {
                scanf("%lld",&a[i][j]);
            }
        }
        for(int i = 1; i<=m; i++) {
            for(int j = 1; j<=n; j++) {
                a[i][j] = a[i][j] + a[i-1][j] + a[i][j-1] - a[i-1][j-1];
            }
        }
        //从i,j开始 到 i+x-1,j+y-1
        for(int i = 1; i<=m-x+1; i++) {
            for(int j = 1; j<=n-y+1; j++) {
                maxx = max(maxx,a[i+x-1][j+y-1]-a[i+x-1][j-1]-a[i-1][j+y-1]+a[i-1][j-1]);
            }
        }
        printf("%lld\n",maxx);
    }
     
    return 0 ;
}
//DP
#include<bits/stdc++.h>
#define ms(a,b) memset(a,b,sizeof a)
using namespace std;
const int N = 1e3 + 100;
int dp[N][N], n, m, x, y;
int main(){
    int _; cin >> _;
    while (_--){
        int sum = 0;
        cin >> n >> m >> x >> y;
        ms(dp, 0);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++){
                cin >> dp[i][j];
                dp[i][j] += dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
                if (i >= x && j >= y)  sum = max(sum, dp[i][j] - dp[i - x][j] - dp[i][j - y] + dp[i - x][j - y]);
            }
        cout << sum << endl;
    }
}

B - 小A的质数

HDU - 2136

Sample Input

1
2
3
4
5

Sample Output

0
1
2
1
3

思路:

素数筛变形

首先,要这条题目要求是:

给出一个数,求出这个数的最大素数因子是第几个素数。

最先想到的是直接把1000000以内的素数全部求出来打个表,依次去搜索所在的位置就行了,几次尝试之后,如果求素数的时候不用一些比较好的算法很容易超时(LTE),后来选择了一种比较巧妙的方法:从2开始循环,当循环2的时候,把所有2的倍数做上标记,然后到3的时候,把所有3的倍数做上标记,以此类推,此题得解。

数组中前30个数的动态变化过程如下:(标记的数字就是n的最大素数因子位于素数表的次序)

0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 0 1 2 1 0 2 0 1 2 1 0 2 0 1 2 1 0 2 0 1 2 1 0 2 0 1 2 1 0
0 0 1 2 1 0 2 0 1 2 1 0 2 0 1 2 1 0 2 0 1 2 1 0 2 0 1 2 1 0
0 0 1 2 1 3 2 0 1 2 3 0 2 0 1 3 1 0 2 0 3 2 1 0 2 3 1 2 1 0
0 0 1 2 1 3 2 0 1 2 3 0 2 0 1 3 1 0 2 0 3 2 1 0 2 3 1 2 1 0
0 0 1 2 1 3 2 4 1 2 3 0 2 0 4 3 1 0 2 0 3 4 1 0 2 3 1 2 4 0
0 0 1 2 1 3 2 4 1 2 3 0 2 0 4 3 1 0 2 0 3 4 1 0 2 3 1 2 4 0
0 0 1 2 1 3 2 4 1 2 3 0 2 0 4 3 1 0 2 0 3 4 1 0 2 3 1 2 4 0
0 0 1 2 1 3 2 4 1 2 3 0 2 0 4 3 1 0 2 0 3 4 1 0 2 3 1 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 0 4 3 1 0 2 0 3 4 5 0 2 3 1 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 0 4 3 1 0 2 0 3 4 5 0 2 3 1 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 6 4 3 1 0 2 0 3 4 5 0 2 3 6 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 6 4 3 1 0 2 0 3 4 5 0 2 3 6 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 6 4 3 1 0 2 0 3 4 5 0 2 3 6 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 6 4 3 1 0 2 0 3 4 5 0 2 3 6 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 6 4 3 1 7 2 0 3 4 5 0 2 3 6 2 4 0
0 0 1 2 1 3 2 4 1 2 3 5 2 6 4 3 1 7 2 0 3 4 5 0 2 3 6 2 4 0

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6;
int a[N], n, idx = 1;
int main() {
	//freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	for (int i = 2; i < N; ++i) {
		if (a[i] == 0) {
			a[i] = idx++;
			for (int j = i + i; j < N; j += i)a[j] = a[i];
		}
	}
	while (cin >> n)cout << a[n] << endl;
}

C - 小A的签到题

CodeForces - 1183A

Examples

Input

432

Output

435

Input

99

Output

103

思路:

水题,直接按题意所给的来即可

#include<bits/stdc++.h>
#define ms(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
ll _, n, a[N];
int main() {
	//freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	for (cin >> n;; n++) {
		int cnt = 0, x = n;
		while (x) { cnt += x % 10; x /= 10; }
		if (cnt % 4 ==0) { cout << n << endl; break; }
	}
}

D - 小A的计算器

HDU - 1237

思路:

模拟题,一开始用C++的string中函数去find和atof进行定位和计算,但WA了,然后很容易想到用栈去做(中缀表达式):使用栈

//WA代码
#include<bits/stdc++.h>
using namespace std;
double compute(string str)
{
	int pos = -1;
	if ((pos = str.find('+', 0)) != -1)
	{
		string str1 = str.substr(0, pos);
		string str2 = str.substr(pos + 1);

		return compute(str1) + compute(str2);
	}
	if ((pos = str.find('-', 0)) != -1)
	{
		string str1 = str.substr(0, pos);
		string str2 = str.substr(pos + 1);

		return compute(str1) - compute(str2);
	}

	if ((pos = str.find('*', 0)) != -1)
	{
		string str1 = str.substr(0, pos);
		string str2 = str.substr(pos + 1);

		return compute(str1) * compute(str2);
	}

	if ((pos = str.find('/', 0)) != -1)
	{
		string str1 = str.substr(0, pos);
		string str2 = str.substr(pos + 1);

		return compute(str1) / compute(str2);
	}
	return atof(str.c_str());
}

int main() {
	string str = "";
	while (1) {
		getline(cin, str);
		if (str == "0")break;
		//cout << str << endl;
		float ret = compute(str);
		printf("%.2lf\n", ret);
	}
}

学习dalao的代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    char s[200];
    double a[200];
    while (gets(s))
    {
        if (strcmp(s, "0") == 0) return 0;
        int k = 0;
        double ans = 0;
        a[k] = atof(&s[0]);//从这个地址开始到遇到非小数点或数字结束,将字符串转化成数字 
        for (int i = 0; s[i] != '\0'; i++)
        {
            if (s[i] == ' ' || isdigit(s[i])) continue;
            else if (s[i] == '+') a[++k] = atof(&s[i + 2]);
            else if (s[i] == '-') a[++k] = -atof(&s[i + 2]);
            else if (s[i] == '*') a[k] *= atof(&s[i + 2]);
            else if (s[i] == '/') a[k] /= atof(&s[i + 2]);
        }
        for (int i = 0; i <= k; i++)
            ans += a[i];
        printf("%.2lf\n", ans);
    }
    return 0;
}

E - 小A的畜牧业

CodeForces - 1255D

S型遍历(奇怪的遍历增加了)

#include <bits/stdc++.h>

using namespace std;

char s[102][102];
int T,n,m,k,c,res[102][102];

int main()
{
	for(cin>>T;T--;)
	{
		cin>>n>>m>>k,c=0;
		for(int i=0;i<n;i++)
			scanf("%s",s[i]);
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				c+=s[i][j]=='R';
		int u=c/k,r=c%k;
		for(int i=0,id=0,cnt=0;i<n;i++)
			for(int j=i&1?m-1:0;j!=(i&1?-1:m);j+=i&1?-1:1)
			{
				cnt+=s[i][j]=='R';
				if(id<r&&cnt==u+2||id>=r&&cnt==u+1) id++,cnt=1;
				res[i][j]=id<10?id+48:(id<36?id+87:id+29);
			}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
				putchar(res[i][j]);
			putchar('\n');
		}
	}
}
posted @ 2020-09-20 11:19  Koshkaaa  阅读(163)  评论(0编辑  收藏  举报