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 ...
随机推荐
- Black And White (DFS 训练题)
G - Black And White ================================================================================ ...
- .Net 面试题 汇总(三)
101.ASP.net的身份验证方式有哪些?分别是什么原理? 答:Windwos(默认)用IIS... From(窗体)用帐户 Passport(密钥) 102.在.net中,配件的意思是? 答:程序 ...
- C#中Equals和= =(等于号)的比较)(转载)
C#中Equals和= =(等于号)的比较) 相信很多人都搞不清Equals和 = =的区别,只是零星的懂一点,现在就让我带大家来进行一些剖析 一. 值类型的比较 对于值类型来说 ...
- php简易实现计划任务
index.php <?php function ceshi(){ $wan = file_get_contents('./wangt_index.txt',true); $jifen = $w ...
- 你真的了解React吗
https://zhufengzhufeng.github.io/zhufengreact/index.html#t21.%E4%BB%80%E4%B9%88%E6%98%AFReact?
- python语法图
- Virtual Host on Apache(Apache上建立虚拟主机)
0. Introduction Usually, we want to build two or more websites on a web server, but we have only one ...
- Linux/CentOS防CC攻击脚本
#!/bin/sh cd /var/log/httpd/ cat access_log|awk > a cp /dev/null access_log cp /dev/null error_lo ...
- 【BZOJ 1269】文本编辑器
题目 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对"文本编辑器"做了一个抽象的定义: Move k:将 ...
- 『Golang』在Golang中使用json
由于要开发一个小型的web应用,而web应用大部分都会使用json作为数据传输的格式,所以有了这篇文章. 包引用 import ( "encoding/json" "gi ...