2017福建省赛 FZU2272~2283
1.FZU2272 Frog
传送门:http://acm.fzu.edu.cn/problem.php?pid=2272
题意:鸡兔同笼通解
题解:解一个方程组直接输出就行
代码如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e5+;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+; int main(){
#ifndef ONLINE_JUDGE
FIN
#endif
int T;
scanf("%d",&T);
while(T--){
int n,m;
cin>>n>>m;
cout<<m/-n<<" "<<*n-m/<<endl;
}
}
2.FZU2273
传送门:http://acm.fzu.edu.cn/problem.php?pid=2273
题意:给你两个三角形,让你判断三角形是相交,相离,还是包含
题解:计算几何模板题,先判断三角形A有没有点在三角形B里面,三角形B有没有点在三角形A里面,然后分情况讨论即可
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
struct point{
int x,y;
}s[][]; double m(point a,point b,point c) //叉积
{
return ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x));
} bool Judge(point u1,point u2,point v1,point v2) //判断两条线段相交情况
{
return (max(u1.x,u2.x)>=min(v1.x,v2.x)&&
max(u1.y,u2.y)>=min(v1.y,v2.y)&&
max(v1.x,v2.x)>=min(u1.x,u2.x)&&
max(v1.y,v2.y)>=min(u1.y,u2.y)&&
m(u1,v1,u2)*m(u1,u2,v2)>=&&
m(v1,u1,v2)*m(v1,v2,u2)>=);
} int line_check(int p,int q) //判断两个三角形是否相交
{
return (Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][])||
Judge(s[p][],s[p][],s[q][],s[q][]));
} int point_check(int p,int q) // 面积法判断点在三角形内
{
double res=fabs(m(s[q][],s[q][],s[q][]));
int ans=;
for(int i=;i<;i++)
{
double res1=fabs(m(s[q][],s[q][],s[p][i]));
double res2=fabs(m(s[q][],s[q][],s[p][i]));
double res3=fabs(m(s[q][],s[q][],s[p][i]));
if(res1+res2+res3==res)
ans++;
}
return ans;
} int main()
{
int t;
cin>>t;
while(t--)
{
for(int i=;i<;i++)
for(int j=;j<;j++)
cin>>s[i][j].x>>s[i][j].y;
int ans1=point_check(,),ans2=point_check(,);
if(ans1==&&ans2==) //如果两个三角形没有一个点在另一个三角形内
{
int ans=line_check(,);
if(ans==)
cout<<"disjoint"<<endl; // 相离
else
cout<<"intersect"<<endl; //相交
}
else if(ans1==||ans2==)
cout<<"contain"<<endl; //否则包含
else
cout<<"intersect"<<endl; //相交
}
return ;
}
3.FZU2275
传送门:http://acm.fzu.edu.cn/problem.php?pid=2275
题意:Alice有数字A,Bob有数字B,他们两个人可以对数字进行 1.删除最后一个数,2.将整个数字反转这两个操作,Alice想要将她的数字变得和Bob一样,Bob不想Alice的数字变得和她的一样,最后如果Alice变得和Bob一样了,则Alice赢,否则Bob赢,问你谁会赢
题解:1.如果Bob长度比Alice的数字长度长的话,Bob只需要不断反转他的数字即可,Alice不可能赢
2.如果Bob的数字为0的话,Alice一定赢
3.如果Bob的数字是Alice的数字的子串或者Bob数字的反转是Alice数字的子串的话,那么Alice一定赢
代码如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e5+;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+;
int Nxt[maxn];
void makeNext(char P[]) {
int m = strlen(P);
Nxt[] = ;
for (int q = , k = ; q < m; ++q) {
while (k > && P[q] != P[k]) k = Nxt[k - ];
if (P[q] == P[k]) k++;
Nxt[q] = k;
}
}
int kmp(char T[], char P[]) {
int n = strlen(T), m = strlen(P);
makeNext(P);
for (int i = , q = ; i < n; ++i) {
while (q > && P[q] != T[i]) q = Nxt[q - ];
if (P[q] == T[i]) q++;
if (q == m) return i - m + ; //Æ¥Åä³É¹¦,·µ»Ø³É¹¦Ê±Ê×λÖÃ
}
return -;//Æ¥Åäʧ°Ü
} int main(){
#ifndef ONLINE_JUDGE
FIN
#endif
char str1[maxn];
char str2[maxn];
char str3[maxn];
int T;
scanf("%d",&T);
while(T--){
cin>>str1>>str2;
int len1=strlen(str1);
int len2=strlen(str2);
for(int i=;i<len2;i++){
str3[len2-i-]=str2[i];
}
if(len2==&&str2[]==''){
cout<<"Alice"<<endl;
continue;
}
str3[len2]='\0';
if(len1<len2){
cout<<"Bob"<<endl;
}else{
int ans1=kmp(str1,str2);
int ans2=kmp(str1,str3);
if(ans1!=-||ans2!=-){
cout<<"Alice"<<endl;
}else cout<<"Bob"<<endl;
}
}
}
4.FZU2277
传送门:http://acm.fzu.edu.cn/problem.php?pid=2277
题意:给你一颗树的结构,有两种操作,1.将给定节点和这个节点的所有子树上的权值 value += x-deep*k ,2.询问这个节点的权值
题解:线段树和的dfs序,线段树维护该区间节点的权值,dfs序修改其子树的权值,具体题解看代码注释
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
#define lson root<<1
#define rson root<<1|1
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 8e5+;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+;
int n,q;
struct node{
int l,r;
LL sum1;//sum1记录需要加上来的数
LL sum2;//sum2记录需要减去的数
}Tree[maxn<<];
int ltid[maxn]; //更新的左区间
int rtid[maxn]; //更新的右区间
int dep[maxn]; //维护每个节点的深度
struct E{
int v,next;
}edge[maxn];
int head[maxn];
int tot,top;
//前向星建图
inline void add(int u,int v){
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
//dfs序查询子树的点权和
void dfs(int u,int deep){
ltid[u]=++top;
dep[u]=deep;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
dfs(v,deep+);
}
rtid[u]=top;
//这样从左到右的一段区间了【lrid,rtid】就表示了节点u的子树权值
return;
}
//建树,节点value值初始化为0
void build(int l,int r ,int root){
Tree[root].l=l;
Tree[root].r=r;
Tree[root].sum1=Tree[root].sum2=;
if(l==r) return;
int mid=(l+r)>>;
build(l,mid,lson);
build(mid+,r,rson);
}
void Add(LL &a,LL b){
a+=b;
a%=mod;
}
//更新节点和子树的sum1和sum2
void push_down(int root){
LL a=Tree[root].sum1;
LL b=Tree[root].sum2;
if(a) Add(Tree[lson].sum1,a);
if(a) Add(Tree[rson].sum1,a);
if(b) Add(Tree[lson].sum2,b);
if(b) Add(Tree[rson].sum2,b);
Tree[root].sum1=Tree[root].sum2=;
} void update(int L,int R,LL x,LL k,int root){
int l=Tree[root].l;
int r=Tree[root].r;
int mid=(l+r)/;
if(L<=l&&r<=R){
//到了需要更改的区间
Add(Tree[root].sum1,x); //sum1加上x
Add(Tree[root].sum2,k); //sum2加上k
return;
}
//更新树
push_down(root);
//更新区间
if(L>mid) update(L,R,x,k,rson);
else if(R<=mid) update(L,R,x,k,lson);
else {
update(L,mid,x,k,lson);
update(mid+,R,x,k,rson);
}
}
LL query(int p,int deep,int root){
if(Tree[root].l==Tree[root].r){
//查询值为 ai+=x-k*deep
return ((Tree[root].sum1-Tree[root].sum2*deep%mod)+mod)%mod;
}
push_down(root);
int mid=(Tree[root].l+Tree[root].r)/;
if(p<=mid) return query(p,deep,lson);
return query(p,deep,rson);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(head,-,sizeof(head));
tot=;top=;
int u;
for(int i=;i<=n;i++){
scanf("%d",&u);
add(u,i);
}
dfs(,);
build(,n,);
int op,v,x,k;
scanf("%d",&q);
while(q--){
scanf("%d",&op);
if(op==){
scanf("%d%d%d",&v,&x,&k);
//注意 因为会出现负数,所以我们每次减的操作变成+,最后查询的时候再减
//用两个值分别存所需要加的数和所需要减的数,最后查询的时候操作即可
update(ltid[v],rtid[v],(x*1LL+dep[v]*1LL*k%mod)%mod,k,);
}else{
scanf("%d",&v);
//查询时用
printf("%lld\n",query(ltid[v],dep[v],));
}
}
}
return ;
}
5.FZU2278
传送门:http://acm.fzu.edu.cn/problem.php?pid=2278
题意:有n张牌需要你去抽,每次抽牌的概率是一样的,你每过(n-1)!天可以抽一张牌,求抽齐所有牌的数学期望值
题解:如果我有a张卡,那么我抽到第a+1张卡的概率是(n-a)/n,那么我抽到第a+1张卡平均就需要n/(n-a)天,每隔(n-1)!天就可以抽一次牌
那么我们最后推出来公式就是(n-1)!*n(1+1/2+1/3+……1/n),因为数字特别大,我们要用到大数的知识
三种写法:
1.c++的大数模板
2.Java 的Bignumber
3.python直接写 果然py是最强的
代码如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std; #define MAXN 9999
#define MAXSIZE 10
#define DLEN 4 class BigNum
{
private:
int a[]; //可以控制大数的位数
int len; //大数长度
public:
BigNum(){ len = ;memset(a,,sizeof(a)); } //构造函数
BigNum(const int); //将一个int类型的变量转化为大数
BigNum(const char*); //将一个字符串类型的变量转化为大数
BigNum(const BigNum &); //拷贝构造函数
BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算 friend istream& operator>>(istream&, BigNum&); //重载输入运算符
friend ostream& operator<<(ostream&, BigNum&); //重载输出运算符 BigNum operator+(const BigNum &) const; //重载加法运算符,两个大数之间的相加运算
BigNum operator-(const BigNum &) const; //重载减法运算符,两个大数之间的相减运算
BigNum operator*(const BigNum &) const; //重载乘法运算符,两个大数之间的相乘运算
BigNum operator/(const int &) const; //重载除法运算符,大数对一个整数进行相除运算 BigNum operator^(const int &) const; //大数的n次方运算
int operator%(const int &) const; //大数对一个int类型的变量进行取模运算
bool operator>(const BigNum & T)const; //大数和另一个大数的大小比较
bool operator>(const int & t)const; //大数和一个int类型的变量的大小比较 void print(); //输出大数
};
BigNum::BigNum(const int b) //将一个int类型的变量转化为大数
{
int c,d = b;
len = ;
memset(a,,sizeof(a));
while(d > MAXN)
{
c = d - (d / (MAXN + )) * (MAXN + );
d = d / (MAXN + );
a[len++] = c;
}
a[len++] = d;
}
BigNum::BigNum(const char*s) //将一个字符串类型的变量转化为大数
{
int t,k,index,l,i;
memset(a,,sizeof(a));
l=strlen(s);
len=l/DLEN;
if(l%DLEN)
len++;
index=;
for(i=l-;i>=;i-=DLEN)
{
t=;
k=i-DLEN+;
if(k<)
k=;
for(int j=k;j<=i;j++)
t=t*+s[j]-'';
a[index++]=t;
}
}
BigNum::BigNum(const BigNum & T) : len(T.len) //拷贝构造函数
{
int i;
memset(a,,sizeof(a));
for(i = ; i < len ; i++)
a[i] = T.a[i];
}
BigNum & BigNum::operator=(const BigNum & n) //重载赋值运算符,大数之间进行赋值运算
{
int i;
len = n.len;
memset(a,,sizeof(a));
for(i = ; i < len ; i++)
a[i] = n.a[i];
return *this;
}
istream& operator>>(istream & in, BigNum & b) //重载输入运算符
{
char ch[MAXSIZE*];
int i = -;
in>>ch;
int l=strlen(ch);
int count=,sum=;
for(i=l-;i>=;)
{
sum = ;
int t=;
for(int j=;j<&&i>=;j++,i--,t*=)
{
sum+=(ch[i]-'')*t;
}
b.a[count]=sum;
count++;
}
b.len =count++;
return in; }
ostream& operator<<(ostream& out, BigNum& b) //重载输出运算符
{
int i;
cout << b.a[b.len - ];
for(i = b.len - ; i >= ; i--)
{
cout.width(DLEN);
cout.fill('');
cout << b.a[i];
}
return out;
} BigNum BigNum::operator+(const BigNum & T) const //两个大数之间的相加运算
{
BigNum t(*this);
int i,big; //位数
big = T.len > len ? T.len : len;
for(i = ; i < big ; i++)
{
t.a[i] +=T.a[i];
if(t.a[i] > MAXN)
{
t.a[i + ]++;
t.a[i] -=MAXN+;
}
}
if(t.a[big] != )
t.len = big + ;
else
t.len = big;
return t;
}
BigNum BigNum::operator-(const BigNum & T) const //两个大数之间的相减运算
{
int i,j,big;
bool flag;
BigNum t1,t2;
if(*this>T)
{
t1=*this;
t2=T;
flag=;
}
else
{
t1=T;
t2=*this;
flag=;
}
big=t1.len;
for(i = ; i < big ; i++)
{
if(t1.a[i] < t2.a[i])
{
j = i + ;
while(t1.a[j] == )
j++;
t1.a[j--]--;
while(j > i)
t1.a[j--] += MAXN;
t1.a[i] += MAXN + - t2.a[i];
}
else
t1.a[i] -= t2.a[i];
}
t1.len = big;
while(t1.a[len - ] == && t1.len > )
{
t1.len--;
big--;
}
if(flag)
t1.a[big-]=-t1.a[big-];
return t1;
} BigNum BigNum::operator*(const BigNum & T) const //两个大数之间的相乘运算
{
BigNum ret;
int i,j,up;
int temp,temp1;
for(i = ; i < len ; i++)
{
up = ;
for(j = ; j < T.len ; j++)
{
temp = a[i] * T.a[j] + ret.a[i + j] + up;
if(temp > MAXN)
{
temp1 = temp - temp / (MAXN + ) * (MAXN + );
up = temp / (MAXN + );
ret.a[i + j] = temp1;
}
else
{
up = ;
ret.a[i + j] = temp;
}
}
if(up != )
ret.a[i + j] = up;
}
ret.len = i + j;
while(ret.a[ret.len - ] == && ret.len > )
ret.len--;
return ret;
}
BigNum BigNum::operator/(const int & b) const //大数对一个整数进行相除运算
{
BigNum ret;
int i,down = ;
for(i = len - ; i >= ; i--)
{
ret.a[i] = (a[i] + down * (MAXN + )) / b;
down = a[i] + down * (MAXN + ) - ret.a[i] * b;
}
ret.len = len;
while(ret.a[ret.len - ] == && ret.len > )
ret.len--;
return ret;
}
int BigNum::operator %(const int & b) const //大数对一个int类型的变量进行取模运算
{
int i,d=;
for (i = len-; i>=; i--)
{
d = ((d * (MAXN+))% b + a[i])% b;
}
return d;
}
BigNum BigNum::operator^(const int & n) const //大数的n次方运算
{
BigNum t,ret();
int i;
if(n<)
exit(-);
if(n==)
return ;
if(n==)
return *this;
int m=n;
while(m>)
{
t=*this;
for( i=;i<<<=m;i<<=)
{
t=t*t;
}
m-=i;
ret=ret*t;
if(m==)
ret=ret*(*this);
}
return ret;
}
bool BigNum::operator>(const BigNum & T) const //大数和另一个大数的大小比较
{
int ln;
if(len > T.len)
return true;
else if(len == T.len)
{
ln = len - ;
while(a[ln] == T.a[ln] && ln >= )
ln--;
if(ln >= && a[ln] > T.a[ln])
return true;
else
return false;
}
else
return false;
}
bool BigNum::operator >(const int & t) const //大数和一个int类型的变量的大小比较
{
BigNum b(t);
return *this>b;
} void BigNum::print() //输出大数
{
int i;
cout << a[len - ];
for(i = len - ; i >= ; i--)
{
cout.width(DLEN);
cout.fill('');
cout << a[i];
}
}
int main(void)
{
int i,n;
int T;
cin>>T;
while(T--){
BigNum x; //定义大数的对象数组
BigNum ans;
int n;
cin>>n;
x=;
for(int i=;i<=n;i++){
x=x*i;
}
for(int i=;i<=n;i++){
ans=ans+(x/i);
}
ans.print();
cout<<".0"<<endl;
}
}
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
int t;
Scanner sc=new Scanner(System.in);
t=sc.nextInt();
for(int cc=0;cc<t;cc++)
{
BigInteger b=BigInteger.valueOf(1);
int n;
n=sc.nextInt();
for(int i=1;i<=n;i++)
{
b=b.multiply(BigInteger.valueOf(i));
}
BigInteger d=BigInteger.valueOf(0);
for(int i=1;i<=n;i++)
{
BigInteger mm=b.divide(BigInteger.valueOf(i));
d=d.add(mm);
}
System.out.println(d+".0");
}
}
}
6.FZU2281
传送门:http://acm.fzu.edu.cn/problem.php?pid=2281
题意:你手上有m元,可以买和卖货物,货物在n天的价格各不相同,求你n天过后最多可以有多少钱
题解:将货物的价格画成一个曲线,那么我们就可以发现,我们需要在货物价格低的时候买,价格高的时候卖,因为有多个波谷和波峰,就需要对每一个波谷和波峰进行买和卖的操作,这题也是大数,需要用到大数模板
代码如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 3e3+;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+; const int MAXL = 6e3+;
const int MAXN = ;
const int DLEN = ;
class Big {
public:
int a[MAXL], len;
Big(const int b = ) {
int c, d = b;
len = ;
memset(a, , sizeof(a));
while(d > MAXN) {
c = d - (d / (MAXN + )) * (MAXN + );
d = d / (MAXN + );
a[len++] = c;
}
a[len++] = d;
}
Big(const char *s) {
int t, k, index, L;
memset(a, , sizeof(a));
L = strlen(s);
len = L / DLEN;
if(L % DLEN) len++;
index = ;
for(int i = L - ; i >= ; i -= DLEN) {
t = ;
k = i - DLEN + ;
if(k < ) k = ;
for(int j = k; j <= i; j++) t = t * + s[j] - '';
a[index++] = t;
}
}
Big operator/(const LL &b)const {
Big ret;
LL down = ;
for(int i = len - ; i >= ; i--) {
ret.a[i] = (a[i] + down * (MAXN + )) / b;
down = a[i] + down * (MAXN + ) - ret.a[i] * b;
}
ret.len = len;
while(ret.a[ret.len - ] == && ret.len > ) ret.len--;
return ret;
}
bool operator>(const Big &T)const {
int ln;
if(len > T.len) return true;
else if(len == T.len) {
ln = len - ;
while(a[ln] == T.a[ln] && ln >= ) ln--;
if(ln >= && a[ln] > T.a[ln]) return true;
else return false;
} else return false;
}
Big operator+(const Big &T)const {
Big t(*this);
int big = T.len > len ? T.len : len;
for(int i = ; i < big; i++) {
t.a[i] += T.a[i];
if(t.a[i] > MAXN) {
t.a[i + ]++;
t.a[i] -= MAXN + ;
}
}
if(t.a[big] != ) t.len = big + ;
else t.len = big;
return t;
}
Big operator-(const Big &T)const {
int big;
bool flag;
Big t1, t2;
if(*this > T) {
t1 = *this;
t2 = T;
flag = ;
} else {
t1 = T; t2 = *this; flag = ;
}
big = t1.len;
for(int i = ; i < big; i++) {
if(t1.a[i] < t2.a[i]) {
int j = i + ;
while(t1.a[j] == ) j++;
t1.a[j--]--;
while(j > i) t1.a[j--] += MAXN;
t1.a[i] += MAXN + - t2.a[i];
} else t1.a[i] -= t2.a[i];
}
t1.len = big;
while(t1.a[t1.len - ] == && t1.len > ) {
t1.len--;
big--;
}
if(flag) t1.a[big - ] = - t1.a[big - ];
return t1;
}
LL operator%(const int &b)const {
LL d = ;
for(int i = len - ; i >= ; i--) d = ((d * (MAXN + )) % b + a[i]) % b;
return d;
}
Big operator*(const Big &T) const {
Big ret;
int i, j, up, temp, temp1;
for(i = ; i < len; i++) {
up = ;
for(j = ; j < T.len; j++) {
temp = a[i] * T.a[j] + ret.a[i + j] + up;
if(temp > MAXN) {
temp1 = temp - temp / (MAXN + ) * (MAXN + );
up = temp / (MAXN + );
ret.a[i + j] = temp1;
} else {
up = ;
ret.a[i + j] = temp;
}
}
if(up != ) ret.a[i + j] = up;
}
ret.len = i + j;
while(ret.a[ret.len - ] == && ret.len > ) ret.len--;
return ret;
}
void print() {
printf("%d", a[len - ]);
for(int i = len - ; i >= ; i--) printf("%04d", a[i]);
}
};
int a[maxn];
int main(){
int T;
int cas=;
scanf("%d",&T);
while(T--){
int n,m;
printf("Case #%d: ",cas++);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
if(m==){
printf("0\n");
continue;
}
Big ans=m;
int by=n;
for(int i=;i<n;i++){
if(a[i+]>a[i]){
by=i;
break;
}
}
if(by<n){
Big x=ans/a[by],y=ans%a[by];
while(by<n){
int sl=by+;
while(sl<n&&a[sl+]>=a[sl]) sl++;
if(sl==n){
ans=x*a[sl]+y;
break;
}else{
ans=x*a[sl]+y;
by=sl+;
while(by<n&&a[by]>=a[by+]) by++;
if(by<n) x=ans/a[by],y=ans%a[by];
}
}
} LL x=ans%mod;
cout<<x<<endl;
}
}
7.FZU2282
传送门:http://acm.fzu.edu.cn/problem.php?pid=2282
题意:有一个1~n的全排列,你需要对他进行操作,使得至少有k个人的位置在原来的位置,而剩下的人不在本身的位置
题解:错位排列,公式:
代码如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e5+;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+;
LL Jc[maxn];
LL c[maxn];
void calJc() //求maxn以内的数的阶乘
{
Jc[] = Jc[] = ;
Jc[]=;
c[]=;
c[]=;
c[]=;
for(LL i = ; i < maxn; i++){
c[i]=(((i-)%mod)*((c[i-]+c[i-])%mod))%mod;
Jc[i] = Jc[i - ] * i % mod;
}
}
//费马小定理求逆元
LL pow(LL a, LL n, LL p) //快速幂 a^n % p
{
LL ans = ;
while(n)
{
if(n & ) ans = ans * a % p;
a = a * a % p;
n >>= ;
}
return ans;
}
LL niYuan(LL a, LL b) //费马小定理求逆元
{
return pow(a, b - , b);
}
LL C(LL a, LL b) //计算C(a, b)
{
return Jc[a] * niYuan(Jc[b], mod) % mod* niYuan(Jc[a - b], mod) % mod;
}
int main(){
calJc();
int T;
scanf("%d",&T);
while(T--){
int n,k;
scanf("%d%d",&n,&k);
LL ans=;
for(int i=;i<k;i++){
ans=((ans%mod)+(C(n,i)*c[n-i])%mod)%mod;
}
printf("%lld\n",(mod+Jc[n]%mod-ans%mod)%mod);
}
}
8.FZU2283
传送门:http://acm.fzu.edu.cn/problem.php?pid=2283
题意:玩 x棋,Kim先手,给你当前场上的局势和Kim的棋子,每个人都走最优步,问谁可以赢
题解:玩过这个游戏的都知道,只要你场上还有足够的空间并且你占据了中心的那个格子,你是一定赢的,如果不知道为什么,多玩几把就行,所以我们只需要数场上的空格和判断中心即可
代码如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e5+;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+;
char mp[][]; int main(){
#ifndef ONLINE_JUDGE
FIN
#endif
int T;
cin>>T;
while(T--){
char ch;
int cnt=;
for(int i=;i<;i++){
for(int j=;j<;j++){
cin>>mp[i][j];
if(mp[i][j]=='.') cnt++;
}
}
cin>>ch;
int flag;
if(cnt<=){
if(mp[][]==ch||mp[][]=='.') flag=;
else flag=;
}else flag=;
if(flag) cout<<"Kim win!"<<endl;
else cout<<"Cannot win!"<<endl;
}
}
以后一定好好写线段树嘤嘤嘤
2017福建省赛 FZU2272~2283的更多相关文章
- 2017福建省赛 L Tic-Tac-Toe 模拟
Kim likes to play Tic-Tac-Toe. Given a current state, and now Kim is going to take his next move. Pl ...
- 2017福建省赛 FZU 2278 YYS 数学 大数
Yinyangshi is a famous RPG game on mobile phones. Kim enjoys collecting cards in this game. Suppose ...
- 2017 湖南省赛 K Football Training Camp
2017 湖南省赛 K Football Training Camp 题意: 在一次足球联合训练中一共有\(n\)支队伍相互进行了若干场比赛. 对于每场比赛,赢了的队伍得3分,输了的队伍不得分,如果为 ...
- ACM总结——2017区域赛网络赛总结
从省赛回来至今4周,每周周末都在打网络赛,每次都是划水,总结下自己弱弱的ACM吧!划水水~~ 首先是新疆赛区,基本上都是图论相关的东西,全靠队友,自己翻水水,实力躺了5道. 然后是沈阳赛区,终于有点贡 ...
- 2017浙江省赛 A - Cooking Competition ZOJ - 3958
地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3958 题目: "Miss Kobayashi's Drag ...
- 【数论】【原根】【动态规划】【bitset】2017四川省赛 K.2017 Revenge
题意: 给你n(不超过200w)个数,和一个数r,问你有多少种方案,使得你取出某个子集,能够让它们的乘积 mod 2017等于r. 2017有5这个原根,可以使用离散对数(指标)的思想把乘法转化成加法 ...
- hihoCoder 1582 Territorial Dispute 【凸包】(ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1582 : Territorial Dispute 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In 2333, the C++ Empire and the Ja ...
- hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1584 : Bounce 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 For Argo, it is very interesting watching a cir ...
- hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for ...
随机推荐
- golang的加法比C快?
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/142 1.31 晚上的火车回家,在公司还剩两个小时,无心工作,本 ...
- Redis 在springBoot中的一个使用示例
在现系统中使用了一个字典表,更新或插入字典表需要做Redis缓存 @Override @Cache(name = Constants.REDIS_PREFIX_DIC, desc = "变更 ...
- POJ1236_A - Network of Schools _强连通分量::Tarjan算法
Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are connected to a compute ...
- SQL 公用表表达式(CTE)
1.概念 公用表表达式(Common Table Expression)是SQL SERVER 2005版本之后引入的一个特性.CTE可以看作是一个临时的结果集,可以在接下来的一个SELECT,INS ...
- 【python3.X】Scrapy学习途径参考
如何爬取属性在不同页面的itemhttp://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/request-response.html#topics-requ ...
- idea离线安装lombock插件
技术交流群:233513714 安装过程 1.首先找到插件包 插件包可以在两个地方下载,分别是IDEA的官方插件仓库和GitHub里lombok-intellij-plugin仓库中的release包 ...
- ORB-SLAM(五)KeyFrame类
KeyFrame类利用Frame类来构造.对于什么样的Frame可以认为是关键帧以及何时需要加入关键帧,是实现在tracking模块中的. 由于KeyFrame中一部分数据会被多个线程访问修改,因此需 ...
- ubuntu apt-get 使用代理设置,坑爹。。
网上流传的export http_proxy=http://yourproxyaddress:proxyport是行不通的,虽然改了之后wget一类的可以用.当然去改.bashrc也不会有效果. 真正 ...
- Python 3.6 爬取BD电影网
2018-07-10 #coding:utf-8 #coding:utf-8 from lxml import etree import requests import pandas import t ...
- [Java-Idea]解决idea启动项目报错:Unable to open debugger port(127.0.0.1:53046):java.net.SocketException"socket closed
命令行窗口,执行命令:netstat -aon|findstr 9030 查找占用端口的进程 taskkill -f -pid 11331