G. Give Candies
There are N children in kindergarten. Miss Li bought them N candies. To make the process more interesting, Miss Li comes up with the rule: All the children line up according to their student number (1...N), and each time a child is invited, Miss Li randomly gives him some candies (at least one). The process goes on until there is no candy. Miss Li wants to know how many possible different distribution results are there.
Input
The first line contains an integer T, the number of test case.
The next TT lines, each contains an integer N.
1≤T≤100
1≤N≤10^100000
Output
For each test case output the number of possible results (mod 1000000007).
样例输入复制
1 4
样例输出复制
8
题目大意是:一个老师买了N个苹果分给N位同学(这N个同学编了不同的号码),问一共有多少种分发?
题解:很容易发现答案就是2^n-1,但是,N有10^100000,会发现快速幂也会超时。所以,就有费马小定理,如下:
ans=2^(n-1)%mod=2^((n-1)%(mod-1)+(n-1)/(mod-1)*(mod-1))%mod=2^((n-1)%(mod-1))%mod*2^((n-1)/(mod-1)*(mod-1))%mod=2^((n-1)%(mod-1))%mod
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
const int maxn = 2e5;
const int mod = 1e9 + 7;
string s;
int n;
long long ipow(long long a, long long x) {
long long ans = 1;
while (x) {
if (x & 1) ans = ans * a % mod;
a = a * a % mod;
x >>= 1;
}
return ans;
}
int main() {
int t;
cin>>t;
while (t--) {
cin >> s;
long long num = 0;
for (int i = 0; i < s.size(); i++) num = (num*10+(s[i]-'0'))%(mod-1);
num = (num-1+mod-1) % (mod-1);
cout << ipow(2, num) << endl;
}
return 0;
}
I. Save the Room
Bob is a sorcerer. He lives in a cuboid room which has a length of A, a width of B and a height of C, so we represent it as A * B * C. One day, he finds that his room is filled with unknown dark energy. Bob wants to neutralize all the dark energy in his room with his light magic. He can summon a 1 * 1 * 2 cuboid at a time to neutralize dark energy. But the cuboid must be totally in dark energy to take effect. Can you foresee whether Bob can save his room or not?
Input
Input has T test cases. T≤100
For each line, there are three integers A, B, C
1≤A,B,C≤100
Output
For each test case, if Bob can save his room, print"Yes"
, otherwise print"No"
.
样例输入复制
1 1 2 1 1 4 1 1 1
样例输出复制
Yes Yes No
题目大意:给一个方体的长宽高,填入1*1*2的小方体,问能否填满
题解:感觉有点水,也不水(哈哈~),应该一会就能发现答案就是 a*b*c%2=0就YES
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.in","w+",stdout);
int A, B, C;
while(cin>>A>>B>>C)
{
int flag = 0;
if(A%2==0||B%2==0||C%2==0) flag = 1;
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
B. Mathematical Curse
A prince of the Science Continent was imprisoned in a castle because of his contempt for mathematics when he was young, and was entangled in some mathematical curses. He studied hard until he reached adulthood and decided to use his knowledge to escape the castle.
There are NN rooms from the place where he was imprisoned to the exit of the castle. In the i^{th}ith room, there is a wizard who has a resentment value of a[i]a[i]. The prince has MM curses, the j^{th}jth curse is f[j]f[j], and f[j]f[j] represents one of the four arithmetic operations, namely addition('+'
), subtraction('-'
), multiplication('*'
), and integer division('/'
). The prince's initial resentment value is KK. Entering a room and fighting with the wizard will eliminate a curse, but the prince's resentment value will become the result of the arithmetic operation f[j]f[j] with the wizard's resentment value. That is, if the prince eliminates the j^{th}jth curse in the i^{th}ith room, then his resentment value will change from xx to (x\ f[j]\ a[i]x f[j] a[i]), for example, when x=1, a[i]=2, f[j]=x=1,a[i]=2,f[j]='+'
, then xx will become 1+2=31+2=3.
Before the prince escapes from the castle, he must eliminate all the curses. He must go from a[1]a[1] to a[N]a[N] in order and cannot turn back. He must also eliminate the f[1]f[1] to f[M]f[M] curses in order(It is guaranteed that N\ge MN≥M). What is the maximum resentment value that the prince may have when he leaves the castle?
Input
The first line contains an integer T(1 \le T \le 1000)T(1≤T≤1000), which is the number of test cases.
For each test case, the first line contains three non-zero integers: N(1 \le N \le 1000), M(1 \le M \le 5)N(1≤N≤1000),M(1≤M≤5) and K(-1000 \le K \le 1000K(−1000≤K≤1000), the second line contains NN non-zero integers: a[1], a[2], ..., a[N](-1000 \le a[i] \le 1000)a[1],a[2],...,a[N](−1000≤a[i]≤1000), and the third line contains MM characters: f[1], f[2], ..., f[M](f[j] =f[1],f[2],...,f[M](f[j]='+','-','*','/'
, with no spaces in between.
Output
For each test case, output one line containing a single integer.
样例输入复制
3 2 1 5 2 3 / 3 2 1 1 2 3 ++ 4 4 5 1 2 3 4 +-*/
样例输出复制
2 6 3
题目大意:在给定的N个数中依次使用M个运算符,初始值为K,求最大值。
题解(学习一位大神的题解):
动态规划,设状态dp[i][j]表示取前i个数,j个字符时能获得的最值(最大和最小值都要维护)
设mul(dp,i,j)表示之前的结果为dp,第i个数字第j个运算符运算后的结果
有转移方程:
dpmax[i][j]=max(dpmax[i-1][j],mul(dpmax[i-1][j-1],i,j),mul(dpmin[i-1][j-1],i,j))
//别忘了负数乘以负数可能会转移到最大值。最小值同理。
dpmin同上(详见代码)
边界自然是
dpmax=-inf
dpmin=inf
dp[i][0]=k
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dpmin[1005][10];
ll dpmax[1005][10];
ll const inf=0x3f3f3f3f3f3f;
int numb[1005];
char s[10];
inline ll mul(ll v,int i,int j){
switch(s[j]){
case '+':return v+numb[i];
case '-':return v-numb[i];
case '*':return v*numb[i];
case '/':return v/numb[i];
}
return 0;
}
int main(){
int T;
cin>>T;
int n,m,k;
while(T--){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%d",numb+i);
}
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
dpmax[i][j]=-inf;
dpmin[i][j]=inf;
}
}
dpmin[0][0]=dpmax[0][0]=k;
getchar();
gets(s+1);
for(int i=1;i<=n;i++){
dpmin[i][0]=k;
dpmax[i][0]=k;
for(int j=1;j<=m;j++){
dpmin[i][j]=dpmin[i-1][j];
dpmax[i][j]=dpmax[i-1][j];
if(dpmax[i-1][j-1]!=-inf)
dpmax[i][j]=max(dpmax[i][j],mul(dpmax[i-1][j-1],i,j));
if(dpmin[i-1][j-1]!=inf)
dpmax[i][j]=max(dpmax[i][j],mul(dpmin[i-1][j-1],i,j));
if(dpmin[i-1][j-1]!=inf)
dpmin[i][j]=min(dpmin[i][j],mul(dpmin[i-1][j-1],i,j));
if(dpmax[i-1][j-1]!=-inf)
dpmin[i][j]=min(dpmin[i][j],mul(dpmax[i-1][j-1],i,j));
}
}
cout<<dpmax[n][m]<<endl;
}
}