ACM训练赛第16场

ACM训练赛第16场

问题 F: Exam Manipulation

时间限制: 1 Sec 内存限制: 128 MB
题目描述
A group of students is taking a True/False exam. Each question is worth one point. You, as their teacher, want to make your students look as good as possible—so you cheat! (I know, you would never actually do that.) To cheat, you manipulate the answer key so that the lowest score in the class is as high as possible.
What is the best possible lowest score you can achieve?
输入
The first line of input contains two integers n (1 ≤ n ≤ 1,000) and k (1 ≤ k ≤ 10), where n is the number of students, and k is the number of True/False questions on the exam.
Each of the next n lines contains a string of length k, consisting only of upper-case ‘T’ and upper-case ‘F’. This string represents the answers that a student submitted, in the order the questions were given.
输出
Output, on a single line, the best possible lowest score in the class.
样例输入 Copy
【样例1】
5 4
TFTF
TFFF
TFTT
TFFT
TFTF
【样例2】
3 5
TFTFT
TFTFT
TFTFT
样例输出 Copy
【样例1】
2
【样例2】
5

思路

二进制枚举

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define INF 0x3f3f3f3f

int n,k;
char ch;
int choose[15], minn, ans;
int  a[1005][15];
int temp[1005][15];

int main() {
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i ++) {
        getchar();
        for (int j = 0; j < k; j ++) {
            scanf("%c", &ch);
            a[i][j] = ch == 'T' ? 1 : 0;
        }
    }
    for (int i = 0; i < 1 << k; i ++) { // 枚举所有状态 
        for (int j = 0; j < k; j ++) {
			choose[j] = (i >> j) & 1; // 某列选还是不选 
        }
        minn = INF;
        for (int j = 0; j < n; j ++) {
            int sum = 0;
            for (int p = 0; p < k; p ++) { // 计算最低分 
                temp[j][p] = choose[p] ^ a[j][p]; //0变1,1变0 
                sum += temp[j][p];
            }
            if (sum < minn)
				minn = sum;
        }
        if(minn > ans) // 求最低分最高 
            ans = minn;
    }
    cout << ans << endl;
    return 0;
}

问题 J: Magic Trick

时间限制: 1 Sec 内存限制: 128 MB
题目描述
You are performing a magic trick with a special deck of cards.
You lay out the cards in a row from left to right, face up. Each card has a lower-case letter on it.
Two cards with the same letter are indistinguishable. You select an audience member to perform an operation on the cards. You will not see what operation they perform.
The audience member can do one of two things—they can either select any two cards and swap them, or leave the cards untouched.
In order for the trick to succeed, you must correctly guess what the audience member did—either you guess that the audience member did nothing, or you point at the two cards the audience member
swapped.
Given a string that represents the initial arrangement of the cards, can you guarantee that you will always be able to guess the audience member’s operation correctly, no matter what operation they
perform?
输入
The input consists of a single line containing the string s (1 ≤ |s| ≤ 50), which represents the initial arrangement of the cards, in the order they appear in the row. The string contains only lower-case letters (‘a’–‘z’).
输出
Output a single line with 1 if you can guarantee that you will always be able to guess the audience member’s operation correctly, or 0 otherwise.
样例输入 Copy
【样例1】
robust
【样例2】
icpc
样例输出 Copy
【样例1】
1
【样例2】
0

思路

签到

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
 
using namespace std;
 
bool vis[100];
 
int main()
{
    string s;
    cin >> s;
    for (int i = 0; i < s.length(); i ++) {
        if (vis[s[i] - 'a']) {
            cout << 0 << endl;
            return 0;
        } else {
            vis[s[i] - 'a'] = true;
        }
    }
    cout << 1 <<endl;
    return 0;
}

问题 K: Missing Number

时间限制: 1 Sec 内存限制: 128 MB
题目描述
You are teaching kindergarten! You wrote down the numbers from 1 to n, in order, on a whiteboard.
When you weren’t paying attention, one of your students erased one of the numbers.
Can you tell which number your mischievous student erased?
输入
The first line of input contains a single integer n (2 ≤ n ≤ 100), which is the number of numbers that you wrote down.
The second line of input contains a string of digits, which represents the numbers you wrote down (minus the one that has been erased). There are no spaces in this string. It is guaranteed to contain all of the numbers from 1 to n, in order, except for the single number that the student erased.
输出
Output a single integer, which is the number that the tricky student erased.
样例输入 Copy
【样例1】
5
1235
【样例2】
10
1234568910
【样例3】
15
1234567891012131415
样例输出 Copy
【样例1】
4
【样例2】
7
【样例3】
11

思路

签到

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
 
using namespace std;
 
int main()
{
    string s;
    int n;
    cin >> n;
    cin >> s;
    int cnt = 1;
    for (int i = 0; i < s.length(); i ++) {
        if (cnt == s[i] - '0') {
            cnt ++;
            continue;
        } else if (cnt == (s[i] - '0') * 10 + s[i + 1] - '0'){
            cnt ++;
            i ++;
            continue;
        } else if (cnt == (s[i] - '0') * 100 + (s[i + 1] - '0') * 10 + s[i + 2] - '0') {
            cnt += 2;
            i += 2;
            continue;
        } else {
            cout << cnt << endl;
            return 0;
        }
    }
    if (cnt != n + 1) {
        cout << n << endl;
    }
    return 0;
}

问题 M: Rating Problems

时间限制: 1 Sec 内存限制: 128 MB Special Judge
题目描述
Your judges are preparing a problem set, and they’re trying to evaluate a problem for inclusion in the set. Each judge rates the problem with an integer between −3 and 3, where:
3 means: I really like this problem!
−3 means: I really don’t like this problem!
0 means: Meh. I don’t care if we use this problem or not.
The overall rating of the problem is the average of all of the judges’ ratings—that is, the sum of the ratings divided by the number of judges providing a rating.
Some judges have already rated the problem. Compute the minimum and maximum possible overall rating that the problem can end up with after the other judges submit their ratings.
输入
The first line of input contains two integers n (1 ≤ n ≤ 10) and k (0 ≤ k ≤ n), where n is the total number of judges, and k is the number of judges who have already rated the problem.
Each of the next k lines contains a single integer r (−3 ≤ r ≤ 3). These are the ratings of the k judges that have already rated the problem.
输出
Output two space-separated floating point numbers on a single line, which are the minimum and maximum overall rating the problem could achieve after the remaining judges rate the problem,minimum first. These values must be accurate to an absolute or relative error of 10−4 .
样例输入 Copy
【样例1】
5 2
1
2
【样例2】
4 4
-3
-3
-2
-3
样例输出 Copy
【样例1】
-1.2 2.4
【样例2】
-2.75 -2.75

思路

签到

#include<bits/stdc++.h>
using namespace std;
int n,m,sum,a[20];
double mi,ma;
int main() {
    cin>>n>>m;
    for(int i=1; i<=m; i++) {
        cin>>a[i];
        sum+=a[i];
    }
    mi=1.0*(sum-3*(n-m))/n;
    ma=1.0*(sum+3*(n-m))/n;
       printf("%.5lf %.5lf",mi,ma);
    return 0;
}

问题 N: Triangular Collection

时间限制: 1 Sec 内存限制: 128 MB
题目描述
Call a set of positive integers triangular if it has size at least three and, for all triples of distinct integers from the set, a triangle with those three integers as side lengths can be constructed.
Given a set of positive integers, compute the number of its triangular subsets.
输入
The first line of input contains a single integer n (1 ≤ n ≤ 50), which is the number of integers in the set.
Each of the the next n lines contains a single integer x (1 ≤ x ≤ 109 ). These are the elements of the set. They are guaranteed to be distinct.
输出
Output a single integer, which is the number of triangular subsets of the given set.
样例输入 Copy
【样例1】
5
3
1
5
9
10
【样例2】
10
27
26
17
10
2
14
1
12
23
39
样例输出 Copy
【样例1】
2
【样例2】
58

思路

给定n条边,求能组成三角形的子集个数,首先将给定数组排序,定义三个指针,分别枚举三角形的三条边,若前两个指针能保证指向的元素大于第三个指针指向的元素,则表明后两个指针所包围的元素一定能组成三角形,根据非空集合公式2^n - 1可求集合个数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll sum;
int n,a[55];
int main() {
    cin>>n;
    for(int i=1; i<=n; i++) {
        cin>>a[i];
    }
    sort(a+1,a+n+1);
    for(int i=1; i<=n-2; i++) {
        for(int j=i+2; j<=n; j++) {
            int k=0;
            for(k=i+1; k<=j; k++) {
                if(a[k]+a[i]>a[j])
                    break;
            }
            sum+=(pow(2,j-k)-1);
        }
    }
    cout<<sum;
    return 0;
}

问题 P: Unread Messages

时间限制: 1 Sec 内存限制: 128 MB
题目描述
There is a group of people in an internet email message group. Messages are sent to all members of the group, and no two messages are sent at the same time.
Immediately before a person sends a message, they read all their unread messages up to that point.
Each sender also reads their own message the moment it is sent. Therefore, a person’s unread messages are exactly the set of messages sent after that person’s last message.
Each time a message is sent, compute the total number of unread messages over all group members.
输入
The first line of input contains two integers n (1 ≤ n ≤ 10^9 ) and m (1 ≤ m ≤ 1,000), where n is the number of people in the group, and m is the number of messages sent. The group members are
identified by number, 1 through n.
Each of the next m lines contains a single integer s (1 ≤ s ≤ n), which is the sender of that message. These lines are in chronological order.
输出
Output m lines, each with a single integer, indicating the total number of unread messages over all group members, immediately after each message is sent.
样例输入 Copy
【样例1】
2 4
1
2
1
2
【样例2】
3 9
1
2
3
2
1
3
3
2
1
样例输出 Copy
【样例1】
1
1
1
1
【样例2】
2
3
3
4
3
3
5
4
3

思路

模拟,离散化。由题意可知,人数为1e9,而需要的消息数为1000,只需要维护这1000条数据即可,所以需要离散化。然后模拟即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>

using namespace std;

map<int,int>mp;

typedef long long ll;

int nums[1005];//当前
int peo[1005],cnt;
int n,m,a[1005];

int ffind(int x) {
    for(int i=1; i<=cnt; i++) {
        if(peo[i]==x)
            return 1;
    }
    return 0;
}

ll sum;//mp[a]=b//表示编号为a的人的序号为b
//num[x]=y表示序号为x的人当前未读消息数位y
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++) {
        scanf("%d",&a[i]);
        if(!ffind(a[i])) {
            peo[++cnt]=a[i];
            mp[a[i]]=cnt;
        }
    }
//  for(int i=1;i<=cnt;i++)
//  cout<<peo[i]<<" ";
//  cout<<cnt;
    for(int i=1; i<=m; i++) {
        sum+=n-1;
    //  printf("%d的未读消息数位%d\n",a[i],nums[mp[a[i]]]);
        sum-=nums[mp[a[i]]];
        nums[mp[a[i]]]=0;
        for(int j=1; j<=cnt; j++) {
            if(j!=mp[a[i]])
                nums[j]++;
        }
        cout<<sum<<endl;
    }
    return 0;
}

在此,感谢队友深厚的数学功底!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值