ACM入门(一)

ACM入门(一)

P1421 小玉买文具


把元化为角即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int a, b;
int main()
{
	scanf("%d %d", &a, &b);
	int res = a * 10 + b;
	int one = 19;
	printf("%d", res / one);
	return 0;
}

P1909 买铅笔


这里要使用到排序,并且由于具有多关键字,所以要用pair,考虑使用vector来存放

其中自己重写sort的cmp函数时,>代表降序,<代表升序

原来只能买一种,都不需要排序了。。。

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int a, b;
int n;
int cmp(const pair<int,int>&x, const pair<int,int>&y)
{
	return double(x.second)/x.first < double(y.second)/y.first;
}
int main()
{
	scanf("%d", &n);
	vector<pair<int, int>> res;
	for (int i = 0; i < 3; i++)
	{
		int num, price;
		scanf("%d %d", &num, &price);
		res.push_back(make_pair(num, price));
	}
	//sort(res.begin(), res.end(), cmp);
	long long int  min = 0x3f3f3f3f;
     vector<pair<int, int>>::iterator p = res.begin();
	for (; p != res.end(); p++)
	{
		int m = n;
		int temp = n / (*p).first;
		int counts = temp * (*p).first;
		m -= counts;
		int price = 0;
		price = temp * (*p).second;
		if (m > 0)
			price += (*p).second;
		if (price < min)
			min = price;
	}
	printf("%lld", min);
	return 0;
}

P1089 津津的储蓄计划


直接模拟即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

int main()
{
	int total = 0;
	int save = 0;
	for (int i = 0; i < 12; i++)
	{
		int surplus = 300;
		int cost;
		scanf("%d", &cost);
		surplus -= cost;
		total += surplus;
		if (total >= 100)
		{
			int nums = total / 100;
			save += nums * 100;
			total -= nums * 100;
		}
		if (total < 0)
		{
			printf("-%d", i + 1);
			return 0;
		}



	}
	printf("%d", total + int(save * 1.2));





	return 0;
}

P1085 不高兴的津津


直接模拟即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

int main()
{
	int res = 0;
	int max = 0;
	for (int i = 0; i < 7; i++)
	{
		int a, b;
		scanf("%d %d", &a, &b);
		int temp = a + b-8;
		if (temp > max)
		{
			max = temp;
			res = i + 1;
		}


	}
	printf("%d", res);
	return 0;
}

P1980 级数求和


直接模拟即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

int main()
{
	double k;
	scanf("%lf", &k);
	double res = 1;
	double n = 1;
	while (res <= k)
	{

		n++;
		res += 1 / n;

	}
	printf("%d", int(n));

	return 0;
}

P1980 计数问题


关键点在于对0的判断

考虑比较笨的方法,记录下第一个不是0的位置,单独考虑

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

int counts(int n,int flag)
{
	int res = 0;
	int count = 1000000;
	int firstplace = 1;
	int count_0 = 0;
	for (int i = 0; i <=6; i++)
	{
		int temp = n / count;
		if (temp == flag)
			res++;
		if (temp > 0)
		{
			if (7 - i > firstplace)
				firstplace = 7 - i;
		}
		else
		{
			if (firstplace != 1)
				count_0++;


		}
		n -= temp * count;
		count = count / 10;
	}
	if (flag != 0)
		return res;
	else
		return count_0;

}
int main()
{
	int n, flag;
	scanf("%d %d", &n, &flag);
	int res = 0;
	for (int i = 1; i <= n; i++)
	{
		res += counts(i, flag);
	}
	printf("%d", res);
	return 0;
}

其实直接从数来考虑就可以了。。

还是做复杂了

P1014 Cantor表


规律比较难归纳,考虑一个个模拟

通过奇偶不同进行归纳

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	int a = 1;
	int b = 1;
	for (int i = 1; i != n; i++)
	{
		if (b == 1&&(a%2==0))
		{
			
			a++;
		}
		else if (a == 1&&(b%2==1))
		{
			b++;
		}
		else
		{
			//考虑是增是减
			if ((a + b) % 2 == 1)
			{
				a++;
				b--;
			}
			else
			{
				a--;
				b++;
			}
		}

	}
	printf("%d/%d", a, b);
	return 0;
}

P1307 数字反转


最主要是解决前导0和负号的问题

显然使用字符串来解决应该比用整数来解决合理

注意特殊情况0

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int main()
{
	char str[100];
	scanf("%s", str);
	if (str[0] == '0')
	{
		printf("0");
		return 0;
	}
	bool flag = 0;
	if (str[0] == '-')
		flag = 1;
	//记录下负号
	reverse(str,str+strlen(str));
	//反转
	//输出注意前导0即可
	if (flag)
		printf("-");
	int i = 0;
	while (str[i] == '0')
		i++;
	while (str[i] != '-' && str[i] != 0)
	{
		printf("%c", str[i]);
		i++;
	}
	return 0;
}

P1046 陶陶摘苹果


模拟即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int a[10];
	int n;
	for (int i = 0; i < 10; i++)
		scanf("%d", &a[i]);
	scanf("%d", &n);
	int res = 0;
	for (int i = 0; i < 10; i++)
	{
		if (a[i] <= n + 30)
			res++;
	}
	printf("%d", res);
	return 0;
}

P1047 校门外的树


主要考虑边界重合的情况

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int a[10001];
int main()
{
	int l, m;
	scanf("%d %d", &l, &m);
	memset(a, -1, sizeof(int) * (l+1));
	for (int i = 0; i < m; i++)
	{
		int min, max;
		scanf("%d %d", &min, &max);
		memset(a + min, 0, sizeof(int) * (max - min+1));

	}
	int res = 0;
	for (int i = 0; i <= l; i++)
		if (a[i] == -1)
			res++;
	printf("%d", res);
	return 0;
}

P1427 小鱼的数字游戏


逆置即可

这里要注意中间差个1 (a,a+n) 从a开始要n+1

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll a[101];
int main()
{
	int i = 0;
	while (1)
	{
		scanf("%lld", &a[i]);
		if (a[i] == 0)
			break;
		i++;
	}
	reverse(a, a + i);
	for (int j = 0; j < i; j++)
		printf("%lld ", a[j]);
	return 0;
}

P2141 珠心算测验


注意题意,只是看集合内的数是否能表示为其他两个数之和

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
bool  a[20001];
ll b[101];
int main()
{
	int n;
	scanf("%d", &n);
	memset(a, 0, sizeof(a));
	for (int i = 0; i < n; i++)
	{
		
		scanf("%lld", &b[i]);
		a[b[i]] = 1;
	}
	sort(b, b + n);
	int res = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = i + 1; j < n; j++)
		{
			if (a[b[i] + b[j]] == 1)
			{
				res++;
				a[b[i] + b[j]] = 0;
			}
		}
	}
	printf("%d", res);
	return 0;
}

P5594 模拟赛


使用bool开的数组可真大!

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
bool a[1001][1001];
int main()
{
	int n, m, k;
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			int d;
			scanf("%d", &d);
			a[d-1][j] = 1;
		}
	}
	for (int i = 0; i < k; i++)
	{
		int res = 0;
		for (int j = 0; j < m; j++)
			if (a[i][j] == 1)
				res++;
		printf("%d ", res);
	}
	return 0;
}

P5015 标题统计


单纯的输入问题

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
char str[10000];
int main()
{
	cin.getline(str, 10000);
	int res = 0;
	for (int i = 0; i < strlen(str); i++)
	{
		if (str[i] != ' ' && str[i] != '\n')
			res++;

	}
	printf("%d", res);
	return 0;
}

P1055 ISBN号码


直接模拟即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
char str[20];
int main()
{
	scanf("%s", str);
	int a[10];
	for (int i = 0, j = 0; str[i] != 0; i++)
	{
		if (str[i] != '-')
		{
			a[j] = str[i]-48;
			j++;
		}
	}
	int res = 0;
	for (int i = 0; i < 9; i++)
		res += a[i] * (i + 1);
	res %= 11;
	char ch;
	if (res == 10)
		ch = 'X';
	else
		ch = res + '0';

	if (str[12] == ch)
		printf("Right");
	else
	{
		for (int i = 0; i < 9; i++)
		{
			printf("%d", (a[i]));
			if (i == 0 || i == 3 || i == 8)
				printf("-");
		}
		printf("%c", ch);
	}

	return 0;
}

P1308 统计单词数


transform(::toupper)

transform(a.begin(), a.end(), a.begin(), ::toupper);

其中a是string类

strstr

strstr是在一个字符串里面给定一个字符串,寻找有没有这个字符串,若有,返回首次出现的指针否则返回NULL(空指针)

用strstr来判断字符是否存在,注意前后界考虑即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

int main()
{
	char txt[1000001],word[11];
	cin.getline(word, 11);
	cin.getline(txt, 1000001);
	int counts=0, first_place=0;
	transform(txt, txt + strlen(txt), txt, ::toupper);
	transform(word, word + strlen(word), word, ::toupper);
	char* p = txt;
	char* q;
	int len = strlen(word);
	for (; q = strstr(p,word);)
	{
		if (q != NULL
			&& (q == txt||(*(q - 1) == ' '))
			&& ((*(q + len) == 0) || (*(q + len) == ' ')))
		{
			if (counts == 0)
			{
				first_place = q - txt;
			}
			counts++;
		}
		p = q + len;//关键!
	}
	if (counts == 0)
		printf("-1");
	else
		printf("%d %d", counts, first_place);


	return 0;
}

P2010 回文日期


要注意填充0 比如1月是01

其实总体来说由于只有8位,那么可以由年份来直接确定是否合法即可

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
struct res {
	int year;
	int mon;
	int day;
};
bool judge_leap(int year)
{
	return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0) ? 1 : 0;
}
bool day_valid(res day)
{
	int month_day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	month_day[2] += judge_leap(day.year);
	if (day.mon < 1 || day.mon>12 || day.day<1 || day.day>month_day[day.mon])
		return 0;
	else
		return 1;
}
bool year_size(res day1, res day2)
{
	if (day1.year < day2.year)
		return 1;
	else if (day1.year == day2.year)
	{
		if (day1.mon < day2.mon)
			return 1;
		else if (day1.mon == day2.mon)
		{
			if (day1.day <= day2.day)
				return 1;
			else
				return 0;
		}
		else
			return 0;
	}
	else
		return 0;
}
int main()
{
	res sta;
	res end;
	char temp[9];
	char str[5];
	cin >> temp;
	memcpy(str, temp, sizeof(char) * 4);
	str[4] = 0;
	sta.year = atoi(str);
	memcpy(str, temp + 4, sizeof(char) * 2);
	str[2] = 0;
	sta.mon = atoi(str);
	memcpy(str, temp + 6, sizeof(char) * 2);
	str[2] = 0;
	sta.day = atoi(str);

	cin >> temp;
	memcpy(str, temp, sizeof(char) * 4);
	str[4] = 0;
	end.year = atoi(str);
	memcpy(str, temp + 4, sizeof(char) * 2);
	str[2] = 0;
	end.mon = atoi(str);
	memcpy(str, temp + 6, sizeof(char) * 2);
	str[2] = 0;
	end.day = atoi(str);

	int counts = 0;
	while (sta.year <= end.year)
	{
		//按每年来计算该年的回文日期
		char mon[3];
		char day[3];
		mon[0] = sta.year % 10+'0';
		mon[1] = sta.year%100 / 10 + '0';
		mon[2] = 0;

		day[0] = sta.year %1000/ 100 + '0';
		day[1] = sta.year / 1000 + '0';
		day[2] = 0;
		res temp;
		temp.year = sta.year;
		temp.mon = atoi(mon);
		temp.day = atoi(day);
		if (day_valid(temp) && year_size(temp, end))
			counts++;
		sta.year++;
	}
	printf("%d", counts);
	return 0;
}

%别人直接算日期的做法确实太清晰了

P1012 拼数


sort默认是升序 less

这里直接根据需求来比较即可

自定义cmp函数!! 巧妙

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
bool cmp(string s1, string s2)
{
	return s1 + s2 > s2 + s1;
}
int main()
{
	int n;
	cin >> n;
	string res[21];
	for (int i = 0; i < n; i++)
		cin >> res[i];
	sort(res, res+n,cmp);
	string str;
	for (int i = 0; i < n; i++)
		str += res[i];
	cout << str;


	return 0;
}

P5587 打字练习


注意 inf是指无穷大 一般是除数为0

要注意两个串的长度可能不一样

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
string out[10001];
string in[10001];
int main()
{
	int i = 0;
	while (1)
	{
		getline(cin,out[i]);
		if (out[i] == "EOF")
			break;
		char res[100001];
		if (out[i].find('<') != -1)
		{
			char temp[100001];
			strcpy(temp, (out[i]).c_str());
			//开始往后给

			int pos = 0;
			int k;
			for ( k = 0; temp[k] != 0; k++)
			{
				if (temp[k] == '<')//退格
				{
					if (pos != 0)
						pos--;
				}
				else
				{
					res[pos] = temp[k];
					pos++;
				}
			}
			res[pos] = 0;
			out[i] = res;
		}




		i++;
	}
	int j = 0;
	int counts = 0;
	while (1)
	{
		getline(cin, in[j]);
		if (in[j] == "EOF")
			break;
		//中间存在转换
		char res[100001];
		if (in[j].find('<')!=-1)
		{
			char temp[100001];
			strcpy(temp, (in[j]).c_str());
			//开始往后给
		
			int pos = 0;
			for (int k = 0; temp[k] != 0; k++)
			{
				if (temp[k] == '<')//退格
				{
					if (pos != 0)
						pos--;
				}
				else
				{
					res[pos] = temp[k];
					pos++;
				}
			}
			res[pos] = 0;
		}
		else
			strcpy(res, (in[j]).c_str());
		char aim[100001];
		strcpy(aim, out[j].c_str());
		int len1 = out[j].length();
		int len2 = strlen(res);
		len1 = len1 <= len2 ? len1 : len2;
		for (int k = 0; k < len1; k++)
		{
			if (aim[k] == res[k])
				counts++;
		}

		j++;
	}



	int T;
	cin >> T;
	cout << floor(double(counts)*60 / T+0.5);
	return 0;
}

P1028 数的计算


反向推理

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
int counts = 1;
int a[1001];
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= i / 2; j++)
			a[i] += a[j];
		a[i]++;
	}
	cout << a[n];
	return 0;
}

P1464 Function


直接先递推把数据记录下来

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
int a[21][21][21];
void solve()
{
	for (int i = 0; i <= 20; i++)
	{
		for (int j = 0; j <= 20; j++)
		{
			a[0][i][j] = 1;
			a[i][0][j] = 1;
			a[i][j][0] = 1;
		}
	}
	for (int i = 1; i <=20; i++)
	{
		for (int j = 1; j <= 20; j++)
		{
			for (int k = 1; k <= 20; k++)
			{
				if (i < j && j < k)
					a[i][j][k] = a[i][j][k - 1] + a[i][j - 1][k - 1] - a[i][j - 1][k];
				else
					a[i][j][k] = a[i-1][j][k] + a[i-1][j - 1][k]+a[i-1][j][k-1] - a[i-1][j - 1][k-1];

			}
		}


	}


}
int main()
{
	solve();
	while (1)
	{
		ll aa, b, c;
		scanf("%lld %lld %lld", &aa, &b, &c);
		if (aa == -1 && b == -1 && c == -1)
			break;
		int res;
		
		if (aa <= 0 || b <= 0 || c <= 0)
			res = 1;
		else if (aa > 20 || b > 20 || c > 20)
			res = a[20][20][20];
		else
			res = a[aa][b][c];
		printf("w(%lld, %lld, %lld) = %d\n", aa, b, c, res);

	}
	return 0;
}

%题解之后发现

原来记录下来的方法就是在原来递归语句前加一句等于

eg: rpt[a][b][c]=w(20,20,20)

P5534 等差数列


直接算

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;


int main()
{
	ll a1, a2, d,n;
	scanf("%lld %lld %lld", &a1, &a2, &n);
	d = a2 - a1;
	ll res = n * a1 +((n) * (n - 1) * d) / 2;
	printf("%lld", res);
	return 0;
}

P1192 台阶问题


标准dp但使用递推规律会更快

注意答案要取模

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
int a[100001];
int n, k;
void solve()
{
	a[n] = 1;
	a[n - 1] = 1;
	for (int i = 2; i <= n; i++)
	{
		for (int j = 1; j <= i&&j<=k; j++)
			a[n - i] =(a[n-i]+ a[n - i + j])%100003;
	}
}
int main()
{
	memset(a, 0, sizeof(a));
	scanf("%d %d", &n, &k);
	solve();
	printf("%d", a[0]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值