随机数法

附上题目  poj   3318        与   poj    2454

 

Description      

You are given three n × n matrices A, B and C. Does the equation A × B = C hold true?

Input

The first line of input contains a positive integer n (n ≤ 500) followed by the the three matrices A, B and C respectively. Each matrix's description is a block of n × n integers.

It guarantees that the elements of A and B are less than 100 in absolute value and elements of C are less than 10,000,000 in absolute value.

Output

Output "YES" if the equation holds true, otherwise "NO".

Sample Input

2
1 0
2 3
5 1
0 8
5 1
10 26
Sample Output

YES

 

题意:  给出三个  n*n矩阵     问是否矩阵a*矩阵b      是否会等于矩阵c   (poj 3318)

 

起初以为是一道水题,然后写着写着感觉不对劲了,一定会超时的。           然后被提醒用随机数解题

 

 

解题思路:

    随机得到两个数,分别r,l    ,判断矩阵a,b相乘之后的r行l列的位置,是否会等于c的r行l列的数,多次之后若全满足,则符和,反之输出NO

 

 

 

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
//#include<bits/stdc++.h>
using namespace std;
const int MAX=510;
int n;

struct s{
    int matrix[MAX][MAX];
}a,b,c,R;

int solve(int r,int l)//    代表r行  *   l列 
{
    int ans=0;
    for (int i=1;i<=n;i++){
        ans=ans+a.matrix[r][i]*b.matrix[i][l];
    }
    return ans;
} 

int main()
{
    cin>>n;
    for (int i=1;i<=n;i++){
        for (int j=1;j<=n;j++){
            scanf("%d",&a.matrix[i][j]);//cin>>a.matrix[i][j];
        }
    }
    for (int i=1;i<=n;i++){
        for (int j=1;j<=n;j++){
            scanf("%d",&b.matrix[i][j]);//cin>>b.matrix[i][j];
        }
    }
    for (int i=1;i<=n;i++){
        for (int j=1;j<=n;j++){
            scanf("%d",&c.matrix[i][j]);//cin>>c.matrix[i][j];
        }
    }
    srand((unsigned)time(NULL));
    bool flag=true;
    for (int i=1;i<=100000;i++){
        int r=rand()%n+1;
        int l=rand()%n+1;
        int t1=solve(r,l);
        if (t1!=c.matrix[r][l]){
            flag=false;
            break;
        }
    }
    if (flag)
        printf("YES\n");
    else 
        printf("NO\n");
    return 0;
}

    

 

 

 

 

poj   2454        

Description

In the newest census of Jersey Cows and Holstein Cows, Wisconsin cows have earned three stalls in the Barn of Representatives. 
The Jersey Cows currently control the state's redistricting committee. They want to partition
the state into three equally sized voting districts such that the Jersey Cows are guaranteed to win elections in at least two of the districts.
Wisconsin has 3*K (1 <= K <= 60) cities of 1,000 cows, numbered 1..3*K, each with a known number (range: 0..1,000) of Jersey Cows.
Find a way to partition the state into three districts, each with K cities, such that the Jersey Cows have the majority percentage in at least two of districts. All supplied input datasets are solvable. Input * Line 1: A single integer, K * Lines 2..3*K+1: One integer per line, the number of cows in each city that are Jersey Cows. Line i+1 contains city i's cow census. Output * Lines 1..K: K lines that are the city numbers in district one, one per line * Lines K+1..2K: K lines that are the city numbers in district two, one per line * Lines 2K+1..3K: K lines that are the city numbers in district three, one per line Sample Input 2 510 500 500 670 400 310 Sample Output 1 2 3 6 5 4

 

题意:输入3*k个城市的票数,然后让你进行对城市进行组合成三个区域,要求每个区域城市数均为k,且至少两个区域的票数大于500*k

 

思路:先由大到小排序,然后在【0到k-1】  与【k到2*k-1】    进行随机交换,直到符和条件跳出

#include<iostream>
#include<ctime>
#include<algorithm>
using namespace std;
struct s{
    int num,id;
}a[510];
bool cmp(const s &b,const s &c)     
{
    if(b.num!=c.num) return b.num>c.num;
    return b.id>c.id;
}

void wap(s &a,s &b)
{
    int t=a.num;
    a.num=b.num;
    b.num=t;
    t=a.id;
    a.id=b.id;
    b.id=t;
}

int main()
{
    int k;
    scanf("%d",&k);
    for (int i=0;i<k*3;i++){
        scanf("%d",&a[i].num);
        a[i].id=i+1;
    }
    sort(a,a+3*k,cmp);
    int sum1=0,sum2=0;
    for (int i=0;i<k*2;i++){
        if (i<k)
            sum1+=a[i].num;
        else 
            sum2+=a[i].num;
    }
    srand((unsigned)time(NULL));
    while (sum1<=500*k||sum2<=500*k){
        int t1=rand()%k;
        int t2=rand()%k+k;
        sum1=sum1-a[t1].num+a[t2].num;
        sum2=sum2-a[t2].num+a[t1].num;
        wap(a[t1],a[t2]);
    }
    for (int i=0;i<3*k;i++){
        printf("%d\n",a[i].id);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/q1204675546/p/10491114.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值