Cow_Contest

Description

N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.

The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ A ≤ N; 1 ≤ B ≤ NA ≠ B), then cow A will always beat cow B.

Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.

Input

* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Each line contains two space-separated integers that describe the competitors and results (the first integer, A, is the winner) of a single round of competition: A and B

Output

* Line 1: A single integer representing the number of cows whose ranks can be determined
 

Sample Input

5 5
4 3
4 2
3 2
1 2
2 5

Sample Output

2
#include
#include
#include
#include
#include
#include
using namespace std;

int n,m;
int x,y;
int ans;
bool h;
int map[110][110];

int main()
{
    freopen("C://Users//Lenovo//Desktop//in.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF){
        ans=0;
        memset(map,0,sizeof(map));
        while(m--){
            scanf("%d%d",&x,&y);
            map[x][y]=1;
        }
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                for(int k=1;k<=n;++k){
                    if(map[j][i]&&map[i][k])
                        map[j][k]=1;
                }
            }
        }
        for(int i=1;i<=n;++i){
            h=true;
            for(int j=1;j<=n;++j){
                if(i==j)
                    continue;
                if(map[i][j]==0&&map[j][i]==0){
                    ++ans;
                    break;
                }
            }
        }
        printf("%d\n",n-ans);
    }
    return 0;
}
注意Floyd中是if(map[j][i]&&map[i][k])就怎样怎样,而不是if(map[i][j]&&map[j][k])就怎样怎样,要把中间的那个点的遍历放在第一个for语句中,不知道为什么,放在下面的for语句里就会出错
<think>我们需要检查amp_contest_five_star_person_detail表中的POLICY_CD是否都存在于amp_ac_policy_info表中,关联条件为: amp_contest_five_star_person_detail.AG = amp_ac_policy_info.eaag 和 amp_contest_five_star_person_detail.POLICY_CD = amp_ac_policy_info.polnum 我们可以使用LEFT JOIN或者NOT EXISTS来找出那些在amp_contest_five_star_person_detail表中有记录,但是在amp_ac_policy_info表中没有匹配的记录。 这里提供两种方法: 方法1:使用LEFT JOIN 思路:将amp_contest_five_star_person_detail表左连接amp_ac_policy_info表,然后找出那些连接后amp_ac_policy_info表中相关字段为NULL的记录。 方法2:使用NOT EXISTS 思路:使用子查询,检查在amp_contest_five_star_person_detail表中是否存在记录,其AG和POLICY_CD在amp_ac_policy_info表中没有对应的eaag和polnum。 我们通常更倾向于使用NOT EXISTS,因为它在遇到第一个匹配项时就会停止,可能更高效,尤其是在数据量大的情况下。 但是,我们也可以使用LEFT JOIN并检查右表的主键是否为NULL。 下面分别给出两种方法的SQL语句: 方法1:LEFT JOIN ```sql SELECT d.* FROM amp_contest_five_star_person_detail d LEFT JOIN amp_ac_policy_info p ON d.AG = p.eaag AND d.POLICY_CD = p.polnum WHERE p.eaag IS NULL; -- 或者p.polnum IS NULL,因为这两个条件同时成立 ``` 方法2:NOT EXISTS ```sql SELECT d.* FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ); ``` 以上两个查询都会返回amp_contest_five_star_person_detail表中那些在amp_ac_policy_info表中没有对应保单的记录。 如果我们只是想知道是否存在这样的记录(即是否所有POLICY_CD都存在),我们可以使用以下查询,如果返回记录数为0,则表示都存在。 例如,使用NOT EXISTS的方式统计: ```sql SELECT COUNT(*) AS missing_count FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ); ``` 如果missing_count为0,则说明所有记录都存在。 解释: 1. 在LEFT JOIN方法中,我们通过左连接,将两个表按照AG=eaag和POLICY_CD=polnum进行连接。如果右表中没有匹配的行,则右表的所有列都会是NULL。然后我们通过WHERE p.eaag IS NULL来过滤出这些没有匹配的记录。 2. 在NOT EXISTS方法中,子查询用于检查是否存在匹配的记录。如果子查询没有返回任何行,则NOT EXISTS条件为真,该行就会被选中。 注意:在LEFT JOIN中,我们使用了p.eaag IS NULL作为条件,这是因为eaag在关联条件中,如果连接失败,它必然为NULL。同样,我们也可以使用p.polnum IS NULL,效果一样。 建议:为了性能,确保在关联字段上有索引,即amp_ac_policy_info表的eaag和polnum字段,以及amp_contest_five_star_person_detail表的AG和POLICY_CD字段。 如果我们需要检查某个特定的AG和POLICY_CD是否存在,也可以单独查询,但这里我们需要检查整个表。 现在,我们给出一个完整的示例,假设我们只需要知道缺失的数量,我们可以执行: ```sql SELECT COUNT(*) AS missing_count FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ); ``` 如果missing_count大于0,则说明有记录不存在于amp_ac_policy_info表中。 但是,问题要求查询的是“是否都在”,所以我们可以直接判断这个计数是否为0,如果为0则都在,否则不都在。 因此,我们可以这样写一个查询来返回布尔值(在MySQL中,我们可以使用CASE语句返回一个可读的结果): ```sql SELECT CASE WHEN EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ) ) THEN '存在缺失的保单' ELSE '所有保单都存在' END AS check_result; ``` 或者,我们也可以直接返回缺失的记录,让调用者自己判断。 根据需求,我们可能需要不同的输出。这里我们给出一个返回缺失记录列表的查询,以及一个返回布尔结果的查询。 如果我们需要一个简单的布尔值(在MySQL中,没有布尔类型,我们可以返回0或1): ```sql SELECT IF(COUNT(*) > 0, 0, 1) AS all_exist FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ); ``` 这个查询返回0表示有缺失,1表示全部存在。 但是,注意:如果表很大,这个COUNT(*)可能会比较慢,因为我们不需要知道具体数量,只需要知道是否存在缺失,所以我们可以用LIMIT 1来优化: ```sql SELECT IF( EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ) LIMIT 1 ), 0, 1) AS all_exist; ``` 或者更简洁地,直接利用EXISTS子查询: ```sql SELECT NOT EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ) ) AS all_exist; ``` 这里,最外层的NOT EXISTS:如果存在至少一条在amp_ac_policy_info表中没有匹配的记录,则整个结果为0(false),否则为1(true)。注意:这个查询返回1表示所有记录都存在,0表示存在缺失。 但是,注意:最外层的NOT EXISTS会使得当内层查询有结果时返回0,没有结果时返回1。而内层查询是查找缺失的记录,所以如果内层查询返回了记录(即存在缺失),那么最外层的NOT EXISTS就会是false(0);如果内层查询没有返回记录(即没有缺失),那么最外层的NOT EXISTS就是true(1)。所以这个逻辑是正确的。 因此,我们可以使用这个查询来直接返回一个布尔值(在MySQL中,用1和0表示true和false)。 总结:根据你的需求选择不同的查询语句。 如果只是想查看哪些记录缺失,使用: ```sql SELECT d.* FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ); ``` 如果想返回一个布尔值表示是否全部存在,使用: ```sql SELECT NOT EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ) ) AS all_exist; ``` 这样,如果all_exist为1,则说明所有POLICY_CD都在amp_ac_policy_info表里存在;为0则说明存在缺失。 注意:在大型表上,确保关联字段有索引,否则查询可能会很慢。 最后,根据问题,我们可能需要执行的是检查,所以这里我给出检查缺失记录的查询,因为这样更直观,可以看到哪些记录缺失。 但是,如果问题只是要求一个是否都在的布尔结果,那么第二个查询更合适。 由于问题描述是“查询amp_contest_five_star_person_detail表的POLICY_CD是否都在amp_ac_policy_info表里存在”,所以我们可以直接返回布尔结果。 因此,最终选择返回布尔结果的查询。 但是,如果我们需要在程序中使用,我们可以这样写: ```sql SELECT NOT EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d LEFT JOIN amp_ac_policy_info p ON d.AG = p.eaag AND d.POLICY_CD = p.polnum WHERE p.eaag IS NULL ) AS all_exist; ``` 这个查询使用了LEFT JOIN的方式,然后通过WHERE p.eaag IS NULL来找出缺失的记录,然后最外层的NOT EXISTS来判断是否存在这样的记录。如果存在缺失,则子查询有结果,NOT EXISTS返回0;如果没有缺失,则子查询无结果,NOT EXISTS返回1。 两种方式都可以,性能上可能会有差异,取决于数据分布和索引情况。 我们选择一种即可,这里选择使用NOT EXISTS子查询的方式,因为避免了LEFT JOIN可能产生的临时表。 所以,最终代码: ```sql SELECT NOT EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ) ) AS all_exist; ``` 这个查询将返回一个名为all_exist的列,值为1表示全部存在,0表示存在缺失。 现在,我们可以在MySQL客户端运行这个查询。 注意:如果两个表很大,请确保在关联字段上建立了合适的索引。 例如,在amp_ac_policy_info表上,建议有(eaag, polnum)的复合索引,在amp_contest_five_star_person_detail表上,建议有(AG, POLICY_CD)的复合索引,这样查询才能高效运行。 如果没有索引,查询可能会很慢。 因此,在运行之前,最好检查索引情况。 创建索引的语句(如果还没有索引的话): ```sql -- 为amp_ac_policy_info表创建索引 CREATE INDEX idx_amp_ac_policy_info_eaag_polnum ON amp_ac_policy_info(eaag, polnum); -- 为amp_contest_five_star_person_detail表创建索引 CREATE INDEX idx_amp_contest_detail_ag_policycd ON amp_contest_five_star_person_detail(AG, POLICY_CD); ``` 但是,请注意,创建索引可能会影响写操作的性能,并且需要一定的存储空间,所以请根据实际情况决定。 最后,根据问题,我们给出了解决方案。</think>要检查 `amp_contest_five_star_person_detail` 表的 `POLICY_CD` 是否都存在于 `amp_ac_policy_info` 表中(通过 `AG` 和 `POLICY_CD` 分别关联 `eaag` 和 `polnum`),可以使用以下 SQL 查询: ### 方法 1:使用 LEFT JOIN 查找缺失数据(推荐) ```sql SELECT d.* FROM amp_contest_five_star_person_detail d LEFT JOIN amp_ac_policy_info p ON d.AG = p.eaag AND d.POLICY_CD = p.polnum WHERE p.eaag IS NULL; -- 右表关键字段为 NULL 表示无匹配 ``` ### 方法 2:使用 NOT EXISTS 子查询 ```sql SELECT d.* FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ); ``` ### 方法 3:检查是否存在缺失数据(布尔结果) ```sql SELECT NOT EXISTS ( SELECT 1 FROM amp_contest_five_star_person_detail d WHERE NOT EXISTS ( SELECT 1 FROM amp_ac_policy_info p WHERE d.AG = p.eaag AND d.POLICY_CD = p.polnum ) ) AS all_exist; -- 返回 1(全存在)或 0(有缺失) ``` --- ### 关键解释: 1. **关联逻辑**: - `d.AG = p.eaag` 确保代理机构代码匹配 - `d.POLICY_CD = p.polnum` 确保保单号匹配 2. **性能优化**: - 在 `amp_ac_policy_info(eaag, polnum)` 和 `amp_contest_five_star_person_detail(AG, POLICY_CD)` 上创建复合索引 - 使用 `EXISTS` 通常比 `JOIN` 更高效(找到一条匹配即终止扫描) 3. 结果说明: - 方法 1 和 2 返回缺失的原始数据记录 - 方法 3 直接返回布尔值(1 表示全存在,0 表示有缺失) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值