2020年5月第二周

学习内容

本周没有进行题目练习,对之前的学习内容进行了回顾,把PPT的内容浏览了一遍,把其中的一部分例题又敲了一遍。收藏一些题目还是有用的,平时也应该注意回顾。

题目解决

Sum of Round Numbers
A positive (strictly greater than zero) integer is called round if it is of the form d00…0. In other words, a positive integer is round if all its digits except the leftmost (most significant) are equal to zero. In particular, all numbers from 1 to 9 (inclusive) are round.

For example, the following numbers are round: 40004000, 11, 99, 800800, 9090. The following numbers are not round: 110110, 707707, 222222, 10011001.

You are given a positive integer n ( 1≤n≤104). Represent the number nn as a sum of round numbers using the minimum number of summands (addends). In other words, you need to represent the given number n as a sum of the least number of terms, each of which is a round number.

Input
The first line contains an integer t ( 1≤t≤104) — the number of test cases in the input. Then t test cases follow.

Each test case is a line containing an integer n (1≤n≤104 ).

Output
Print tt answers to the test cases. Each answer must begin with an integer kk — the minimum number of summands. Next, kk terms must follow, each of which is a round number, and their sum is nn. The terms can be printed in any order. If there are several answers, print any of them.

input
5
5009
7
9876
10000
10

output
2
5000 9
1

4
800 70 6 9000 
1
10000 
1
10 
概述
题意就是按权分解,给你一个数,需要你把这个数各个位上的数按权拿出来,比如1234 分解出1000+200+30+4。对于零的时候需要特殊处理一下, 比如1203分分解出1000+200+3。总的来说就是该位上的数字乘以该位的权重。
 

#include<iostream>
using namespace std;
int w[]={1,10,100,1000,10000};
void Round(int n){
	int num=n, k=0, i=0;
	while(num){
		if(num%10) k++;
		num/=10;
	}
	printf("%d\n", k);
	while(n){
		if(n%10){
			printf("%d ", (n%10)*w[i]);
		}
		n/=10;
		i++;
	}
	printf("\n");
}

int main(){
	int t,n;
	scanf("%d", &t);
	while(t--){
		scanf("%d", &n);
		Round(n);
	}
	return 0;
}
#include <bits/stdc++.h>

using namespace std;

int main() {
	int t;
	cin >> t;
	while (t--) {
		int n;
		cin >> n;
		vector<int> ans;
		int power = 1;
		while (n > 0) {
			if (n % 10 > 0) {
				ans.push_back((n % 10) * power);
			}
			n /= 10;
			power *= 10;
		}
		cout << ans.size() << endl;
		for (auto number : ans) cout << number << " ";
		cout << endl;
	}
}

还是需要多参考一下大牛们写的代码,对自己的帮助很大,以后要注意这一点

 

Same Parity Summands

You are given two positive integers n (1≤n≤109) and k (1≤k≤100). Represent the number n as the sum of k positive integers of the same parity (have the same remainder when divided by 2).

In other words, find a1,a2,…,ak such that all ai>0, n=a1+a2+…+ak and either all ai are even or all ai are odd at the same time.

If such a representation does not exist, then report it.

Input
The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Next, t test cases are given, one per line.

Each test case is two positive integers n (1≤n≤109) and k (1≤k≤100).

Output
For each test case print:

YES and the required values ai, if the answer exists (if there are several answers, print any of them);
NO if the answer does not exist.
The letters in the words YES and NO can be printed in any case.

Example

inputCopy
8
10 3
100 4
8 7
97 2
8 8
3 10
5 3
1000000000 9

outputCopy
YES
4 2 4
YES
55 5 5 35
NO
NO
YES
1 1 1 1 1 1 1 1
NO
YES
3 1 1
YES
111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111120

当时做题脑袋懵了,一直死扣样例,就是看不明白这样例到底是怎么来的

我在这找了一份样例测试数据,根据这数据能更好理解题目

Input:
8
10 3
100 4
8 7
97 2
8 8
3 10
5 3
1000000000 9
Output:
YES
4 2 4
YES
55 5 5 35
NO
NO
YES
1 1 1 1 1 1 1 1
NO
YES
3 1 1
YES
111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111120
 
 
10 3
尝试奇数1 1 10-1*2=8,错误
尝试偶数2 2 10-2*2=6,正确
输出
YES
2 2 6
 
100 4
尝试奇数1 1 1 100-1*3=97,正确
输出
YES
1 1 1 97
 
8 7
尝试奇数1 1 1 1 1 1 8-1*6=2,错误
尝试偶数2 2 2 2 2 2 8-2*6=-4,错误
输出
NO
 
97 2
尝试奇数1 97-1*1=96,错误
尝试偶数2 97-2*1=95,错误
输出
NO
 
8 8
尝试奇数1 1 1 1 1 1 1 8-1*7=1,正确
输出
YES
1 1 1 1 1 1 1 1
 
 
3 10
尝试奇数1 1 1 1 1 1 1 1 1 3-1*9=-6,错误
输出
NO
 
5 3
尝试奇数1 1 5-1*2=3,正确
输出
YES
1 1 3
 
1000000000 9
尝试奇数1 1 1 1 1 1 1 1 1000000000-1*8=999999992,错误
尝试偶数2 2 2 2 2 2 2 2 1000000000-2*8=999999984,正确
输出
YES
2 2 2 2 2 2 2 2 999999984
#include <bits/stdc++.h>

using namespace std;

int main() {
	int t;
	cin >> t;
	while (t--) {
		int n, k;
		cin >> n >> k;
		int n1 = n - (k - 1);
		if (n1 > 0 && n1 % 2 == 1) {
			cout << "YES" << endl;
			for (int i = 0; i < k - 1; ++i) cout << "1 ";
			cout << n1 << endl;
			continue;
		}
		int n2 = n - 2 * (k - 1);
		if (n2 > 0 && n2 % 2 == 0) {
			cout << "YES" << endl;
			for (int i = 0; i < k - 1; ++i) cout << "2 ";
			cout << n2 << endl;
			continue;
		}
		cout << "NO" << endl;
	}
}

 

You are given a special jigsaw puzzle consisting of n⋅mn⋅m identical pieces. Every piece has three tabs and one blank, as pictured below.

 

The jigsaw puzzle is considered s在这里插入图片描述olved if the following conditions hold:

  1. The pieces are arranged into a grid with nn rows and mm columns.
  2. For any two pieces that share an edge in the grid, a tab of one piece fits perfectly into a blank of the other piece.

Through rotation and translation of the pieces, determine if it is possible to solve the jigsaw puzzle.

Input

The test consists of multiple test cases. The first line contains a single integer tt (1≤t≤10001≤t≤1000) — the number of test cases. Next tt lines contain descriptions of test cases.

Each test case contains two integers nn and mm (1≤n,m≤1051≤n,m≤105).

Output

For each test case output a single line containing "YES" if it is possible to solve the jigsaw puzzle, or "NO" otherwise. You can print each letter in any case (upper or lower).

Example

input

Copy

3
1 3
100000 100000
2 2

output

Copy

YES
NO
YES

这道题很简单,就看能不能想到这个点子上去。

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        if(n==1||m==1)
        {
            cout<<"YES"<<endl;
            continue;
        }
        if(n+m<=4)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

Card Constructions

input

standard input

output

standard output

A card pyramid of height 11 is constructed by resting two cards against each other. For h>1h>1, a card pyramid of height hh is constructed by placing a card pyramid of height h−1h−1 onto a base. A base consists of hh pyramids of height 11, and h−1h−1 cards on top. For example, card pyramids of heights 11, 22, and 33 look as follows:

You start with nn cards and build the tallest pyramid that you can. If there are some cards remaining, you build the tallest pyramid possible with the remaining cards. You repeat this process until it is impossible to build another pyramid. In the end, how many pyramids will you have constructed?

Input

Each test consists of multiple test cases. The first line contains a single integer tt (1≤t≤10001≤t≤1000) — the number of test cases. Next tt lines contain descriptions of test cases.

Each test case contains a single integer nn (1≤n≤1091≤n≤109) — the number of cards.

It is guaranteed that the sum of nn over all test cases does not exceed 109109.

Output

For each test case output a single integer — the number of pyramids you will have constructed in the end.

Example

input

Copy

5
3
14
15
24
1
output

Copy

1
2
1
3
0

思路:设第i层所需卡片数为a[i],则观察可得a[i]=a[i-1]+3*i-1.

易求出小于1e9的卡片数所能拼出的最高层数是25820,那么让n与25820层~1层依次比较,如果n大于a[i],那么n-=a[i],同时ans++,就能得出答案。有人觉得这道题不能暴力,是用的二分,其实没必要。我的程序里有三层循环,但其实重要的只有前两层循环,运行的时候,第三层循环只在较低几层的卡片中用得着。因此,时间复杂度最高是2*10^7,是能卡过的。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
 
using namespace std;
 
const int N=3e5;
typedef long long ll;
 
int a[N];
 
int main()
{
	int t;
	cin>>t;
	a[1]=2;
	for(int i=2;i;i++) 
	{
		a[i]=a[i-1]+3*i-1;
		if(a[i]>1e9) break;
	}
	while(t--)
	{
		int num;
		cin>>num;
		int ans=0;
		for(int i=25820;i>=1;i--)
		{
			while(num>=a[i])
			{
				num-=a[i];
				ans++;
			}
		}
		cout<<ans<<endl;	
	}
	
	return 0;
}

学习感悟

在思路上与大牛的差距太大了,很多他们感觉理所应当的东西对我来说还是很吃力,平时应该多学习一下他们的思维方式,多多看一下各种高手写出来的代码,吸取经验。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值