Pro
Sco
预计得分: 100+70+80=250 100 + 70 + 80 = 250
实际得分: 90+70+80=240 90 + 70 + 80 = 240
没有 SPJ S P J , T3 T 3 评测得 50 50 ,手测数据得 80 80
Sol
enc
第一题说实话真的好水,就是一个很简单的字符串模拟题
按照题目中的做,就可以得到 90 90 分,(至少我第一次打了 90 90 分)
最后一种情况就是:如果 25 25 个字母都一一对应确定,那么剩下的字母一定对应确定
其实打程序的时候想到这一点了,然而脑子一热,认为输入
25
25
个字母了……
只需要判断是否已经有 25 25 个不相同的字母被确定,然后特殊处理出最后的字母,强制确定
剩下的一一对应就好。
#include<iostream>
#include<cstdio>
using namespace std;
int num1[30] , num2[30] , ans[1005] , len1 , len2 , len3 , flag1 , flag2;
string s[4];
int main() {
freopen("enc.in","r",stdin);
freopen("enc.out","w",stdout);
for(int i=1; i<=3; i++)
cin>>s[i];
len1 = s[1].length() , len2 = s[2].length() , len3 = s[3].length();
if(len1 != len2) {
printf("ERROR");
return 0;
}
for(int i=0; i<len1; i++) {
int id1 = s[1][i] - 'a' + 1;
if(num1[id1]) {
int id2 = s[2][i] - 'a' + 1;
if(num1[id1] != id2) {
printf("ERROR");
return 0;
}
} else {
int id2 = s[2][i] - 'a' + 1;
if(num2[id2]) {
printf("ERROR");
return 0;
} else {
num1[id1] = id2;
num2[id2] = id1;
}
}
}
for(int i=1; i<=26; i++) {
if(num1[i])
flag1++;
if(num2[i])
flag2++;
}
if(flag1 == 25 && flag2 == 25) {
int flag = 0;
for(int i=1; i<=26; i++) {
if(!num1[i])
for(int j=1; j<=26; j++)
if(!num2[j]) {
num1[i] = j;
num2[j] = i;
flag = 1;
break;
}
if(flag)
break;
}
}
for(int i=0; i<len3; i++) {
int id1 = s[3][i] - 'a' + 1;
if(!num2[id1]) {
printf("ERROR");
return 0;
} else
ans[i+1] = num2[id1];
}
for(int i=0; i<len3; i++)
printf("%c",ans[i+1]+'a'-1);
return 0;
}
sort
其实对随便一组数据(样例)简单分析一下,就可以发现本题就是一个裸的 LIS L I S
怎么分析知道考的是LIS呢?其实我们可以把最后的满足条件的想象为放在一个集合内
那么一定要让集合内元素都没有冲突才行
对于这组数据:1 4 2 3
我们可以发现 4 和 2 、3都有冲突
那么4 或者 (2 和 3) 与 1 在集合内(逻辑用语)
显然1 2 3 在一个集合内答案更大
但是我们考虑来自于答案的所有组合: 1 4 或 1 2 3 很容易发现是上升子序列
所以本题可以转化为: LIS L I S 问题。
看数据范围, O(n2) O ( n 2 ) 暴力可过 70 70 分, O(nlogn) O ( n l o g n ) 可过 100 100 分。
100 100 分算法:贪心+二分 或 dp d p +线段树 或 balabala b a l a b a l a ……
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n , num[100005] , low[100005] , ans;
inline int mymax(int a , int b) { return a>b?a:b; }
int main() {
freopen("sort.in","r",stdin);
freopen("sort.out","w",stdout);
memset(low , 0x3f , sizeof(low));
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&num[i]);
low[1] = num[1];
for(int i=2; i<=n; i++) {
int opt = lower_bound(low+1 , low+n+1 , num[i]) - low;
low[opt] = num[i];
ans = mymax(ans , opt);
}
printf("%d",ans);
return 0;
}
game
SPJ S P J !!!
只打了个 O(n3) O ( n 3 ) 的暴力,如果 SPJ S P J 可以的话,可得 80 80 分
100 100 分待更…… (楼下为 80 80 分代码)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n , map[1005][1005];
int main() {
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; i++) {
string s;
cin>>s;
for(int j=0; j<s.length(); j++)
map[i][j+1] = s[j] - 48;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
if(map[i][j] && i!=j) {
for(int k=1; k<=n; k++) {
if(map[j][k] && k!=i && j!=k) {
if(map[k][i]) {
printf("%d %d %d",i , j , k);
return 0;
}
}
}
}
}
printf("-1");
return 0;
}