2019.10.20

**

2019.10.20

**

HDU1213

Today is Ignatius’ birthday. He invites a lot of friends. Now it’s dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with strangers.

One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table.

For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one. So Ignatius needs 2 tables at least.

    Input
    The input starts with an integer T(1<=T<=25) which indicate the number of test cases. Then T test cases follow. Each test case starts with two integers N and M(1<=N,M<=1000). N indicates the number of friends, the friends are marked from 1 to N. Then M lines follow. Each line consists of two integers A and B(A!=B), that means friend A and friend B know each other. There will be a blank line between two cases. 



    Output
    For each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks. 



    Sample Input
    2

5 3
1 2
2 3
4 5

5 1
2 5

    Sample Output
    2

4

en…

一题原原本本的并查集模板题,完全就是套模板,为什么错那么多?完全是对模板不太熟悉,会漏这漏那的。
此题计算需要安排几张桌子,套个模板,最后看看f[]数组的值等于其下标的,就是分成了几类。

.代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<math.h>
#include<string>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int MAX=1e3+10;
int f[MAX];
int n,m;
void init()
{
     for(int i=1;i<=n;i++)
     {
        f[i]=i;
     }
}
int findd(int x)
{
        if(f[x]==x)
                return x;
        f[x]=findd(f[x]);
        return f[x];
}
void merg(int u,int v)
{
        int x=findd(u);
        int y=findd(v);
        if(x==y)
                return ;
        f[y]=x;
}
int main()
{
        int t,i,j,flag;
        while(~scanf("%d",&t))
        {
                flag=0;
                for(j=0;j<t;j++)
                {
                        scanf("%d%d",&n,&m);
                        init();
                        for(i=0;i<m;i++)
                        {
                                int u,v;
                                scanf("%d%d",&u,&v);
                                merg(u,v);
                        }
                        int sum=0;
                        for(i=1;i<=n;i++)
                        {
                                if(f[i]==i)
                                        sum++;
                        }
                        printf("%d\n",sum);
                }
        }
        return 0;
}

HDU1754

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。

这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

    Input
    本题目包含多组测试,请处理到文件结束。 

在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。

学生ID编号分别从1编到N。

第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。

接下来有M行。每一行有一个字符 C (只取’Q’或’U’) ,和两个正整数A,B。

当C为’Q’的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。

当C为’U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

    Output
    对于每一次询问操作,在一行里面输出最高成绩。

    Sample Input
    5 6

1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5

    Sample Output
    5

6
5
9
Hint
Huge input,the C function scanf() will work better than cin

en…

此题如果直接暴力,会TLE,使用线段树的模板就可以了,好吧,我又把模板打错了,T了那么多次。

代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#define MAX 2001000
using namespace std;
int a[MAX],tree[MAX<<1];
void build(int l,int r,int p)
{
        if(l==r)
        {
                tree[p]=a[l];
                return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,p<<1);
        build(mid+1,r,p<<1|1);
        tree[p]=max( tree[p<<1] , tree[p<<1|1] );
}
int Query(int l,int r,int p,int L,int R)
{
     if(L<=l&&r<=R)
     {
             return tree[p];
     }
     int mid=(l+r)>>1;
     int ans=-1;
     if(L<=mid)
        ans=max(ans, Query(l,mid,p<<1,L,R) );
     if(mid<R)
        ans=max(ans, Query(mid+1,r,p<<1|1,L,R) );
     return ans;
}
void Update(int l,int r,int p,int A,int B)
{
        if(l==r) { tree[p]=B; return ; }
        int mid=(l+r)>>1;
        if(A<=mid)
                Update(l,mid,p<<1,A,B);
        else
                Update(mid+1,r,p<<1|1,A,B);
        tree[p]=max( tree[p<<1] , tree[p<<1|1] );
}
int main()
{
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
                int i,j;
                for(i=1;i<=n;i++)
                        scanf("%d",&a[i]);
                build(1,n,1);
                char str[10];
                int A,B;
                for(i=1;i<=m;i++)
                {
                        scanf("%s %d %d",str,&A,&B);
                        if(str[0]=='Q')
                        {
                                printf("%d\n",Query(1,n,1,A,B));
                        }
                        else if(str[0]=='U')
                        {
                                Update(1,n,1,A,B);
                        }
                }
        }
        return 0;
}

HDU1212

As we know, Big Number is always troublesome. But it’s really important in our ACM. And today, your task is to write a program to calculate A mod B.

To make the problem easier, I promise that B will be smaller than 100000.

Is it too hard? No, I work it out in 10 minutes, and my program contains less than 25 lines.

    Input
    The input contains several test cases. Each test case consists of two positive integers A and B. The length of A will not exceed 1000, and B will be smaller than 100000. Process to the end of file. 



    Output
    For each test case, you have to ouput the result of A mod B. 



    Sample Input
    2 3

12 7
152455856554521 3250

    Sample Output
    2

5
1521

en…

看似大数,但可以从最高位开始%B,然后一步步的加上第一位的,sum=sum10;
sum=(sum+a[i]-‘0’)%B
用到同余定理:(a+b)%c=(a%c+b%c)%c=(a+b%c)%c; 附:(a
b)%c=(a%c*b%c)%c;

代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#define MAX 1000
using namespace std;
#define ll long long
char a[MAX];
int main()
{
        int b;
        while(~scanf("%s %d",a,&b))
        {
                int len=strlen(a);
                ll sum=0;
                for(int i=0;i<len;i++)
                {
                        sum=sum*10;
                        sum=(sum+a[i]-'0')%b;
                }
                printf("%d\n",sum);
        }
        return 0;
}

HDU1757

Lele now is thinking about a simple function f(x).

If x < 10 f(x) = x.

If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

And ai(0<=i<=9) can only be 0 or 1 .

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
Input
The problem contains mutiple test cases.Please process to the end of file.

In each case, there will be two lines.

In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )

In the second line , there are ten integers represent a0 ~ a9.
Output
For each case, output f(k) % m in one line.
Sample Input
10 9999
1 1 1 1 1 1 1 1 1 1
20 500
1 0 1 0 1 0 1 0 1 0
Sample Output
45
104

en…

知道要用二维数组做,但是没想到是矩阵快速幂,就没有什么思路

代码

#include<cstdio>
#include<cstring>
#define ll long long
#define maxn 11
ll n,mod;
int ai[maxn];
struct node
{
    ll m[maxn][maxn];
}p,mar;
node mat(node a,node b)
{
        int i,j,k;
        node c;
        for(i=0;i<10;i++)
        {
                for(j=0;j<10;j++)
                {
                        c.m[i][j]=0;
                        for(k=0;k<10;k++)
                        {
                             c.m[i][j]+=a.m[i][k]%mod*b.m[k][j]%mod;
                             c.m[i][j]%=mod;
                        }
                }
        }
        return c;
}
node poww(node x, ll n)
{
        int i,j;
        node ans;
        for(i=0;i<10;i++)
        {
                for(j=0;j<10;j++)
                {
                        if(i==j)
                        ans.m[i][j]=1;
                        else
                        ans.m[i][j]=0;
                }
        }
        while(n)
        {
                if(n&1)
                        ans=mat(ans,x);//ans=ans*x
                n>>=1;
                x=mat(x,x);//x=x*x
        }
    return mat(ans,mar);
}
void init()
{
        int i,j;
        for(i=0;i<10;i++)//初始化单位矩阵
        {
            for(j=0;j<10;j++)
            {
                if(i==j+1)
                        p.m[i][j]=1;
                else
                        p.m[i][j]=0;
            }
        }
        for(i=0;i<10;i++)//把第一行赋值为a1-a9的值
                p.m[0][i]=ai[i];
        int num=9;
        for(i=0;i<10;i++)
        {
                mar.m[i][0]=num--;
        }
}
int main()
{
    int i;
    while (scanf("%lld%lld", &n,&mod)!=EOF)
    {
        for(i=0;i<10;i++)
                scanf("%d",&ai[i]);
            init();
            if(n<10)
                printf("%d\n",n%mod);
            else{
            node ans = poww(p,n-9);
            printf("%lld\n", ans.m[0][0]%mod);
            }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值