(一)UCF Local Programming Contest 2012(Practice)
A - Wall Street Monopoly
题目描述
Given two lots, the cost of fusing those two lots is 100 dollars times the product of the minimum (smaller) dimensions of each lot (in feet).Thus, if one lot is 20’ * 30’ and its adjacent lot is ‘6040’, then the cost of fusing the two lots is 10020*40 = 80,000 (20 is the smaller dimension of the first lot and 40 is the smaller dimension of the second lot). Also, the size of the newly fused lot will be the sum of the length of each lot by the maximum(larger) of the depth of both lots. In this case, the fused lot would be 80’ *40’ (80 feet long and 40 feet deep; 80 is the sum of the lengths and 40 is the larger of the depths). Three adjacent lots with the following dimensions: A-20’*30, B-60’*40’, and C-30’*50’, are shown below:
Given the dimensions (lengths and depths) of several adjacent lots, determine the minimum cost of fusing the separate lots into one.
Input
The first line of the input consists of a single positive integer, n, representing the number of test cases in the input file (i.e., the number of data sets to be processed). The following n lines contain the input cases, one per line. For each input test case, the first integer, k (0 < k < 20), represents the number of lots to be fused. This is followed by k pairs of positive integers less than 101 representing the dimensions (length and depth) of each of the lots in feet, in the order in which they are located.
Output
For each input case, output a single line with the following format:
The minimum cost for lot #m is $X .
where m(l≤m≤n)is the input case number (starting with 1) and X is the integer dollar amount corresponding to the minimum cost to fuse all of the separate lots for that particular input case.
Leave a blank line after the output for each data set. Follow the format illustrated in Sample Output.
Sample Input
2
3 20 30 60 40 30 50
2 10 90 30 40
Sample Output
The minimum cost for lot #1 is $200000.
The minimum cost for lot #2 is $30000.
理解
区间dp
AC代码
#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
const int N = 1e2+5;
ll sum[N],Max[N],dp[N][N],y[N];
void update(int l){
Max[l] = y[l];
for(int i = 1;i < lowbit(l);i <<= 1) Max[l] = max(Max[l],Max[l-i]);
return ;
}
ll query(int l,int r){
ll res = y[r];
while(l <= r){
res = max(res,y[r]);
for(--r;r-l >= lowbit(r);r -= lowbit(r)) res = max(res,Max[r]);
}
return res;
}
void init(int n){
for(int i = 1;i <= n;++i){
for(int j = 1;j <= n;++j)
dp[i][j] = 2e18;
dp[i][i] = 0;
}
return ;
}
int main(){
int n,T,cas = 0;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(Max,0,sizeof(Max));
memset(sum,0,sizeof(sum));
init(n);
for(int i = 1;i <= n;++i){
scanf("%lld%lld",&sum[i],&y[i]);
update(i);
sum[i] += sum[i-1];
}
printf("The minimum cost for lot #%d is ",++cas);
if(n == 1) printf("$0.\n\n");
else{
for(int i = 2;i <= n;++i){
int pre = i-1;
int now = i;
dp[pre][now] = min(sum[pre]-sum[pre-1],y[pre])*min(y[now],sum[now]-sum[now-1]);
}
for(int l = 3;l <= n;++l){
for(int i = 1;i+l-1 <= n;++i){
int j = i+l-1;
for(int k = i;k < j;++k){
ll t1 = min(sum[k]-sum[i-1],query(i,k));
ll t2 = min(sum[j]-sum[k],query(k+1,j));
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+t1*t2);
}
}
}
printf("$%lld.\n\n",dp[1][n]*100);
}
}
return 0;
}
B - The Clock Algorithm
题目描述
In operating systems design, there is a technique called virtual memory, which enables the computer to run a program whose required memory(or logical memory) is larger than the available physical memory of the computer. The memory (for computer and program) are divided into pages, each consisting of a block of fixed size. When a program requests to access a page that is not yet loaded into memory, a page fault occurs. Thus, a page fault will occur the first time each page is accessed. In addition, if the program needs to access more pages than the available memory can provide, one of the pages that were loaded previously will have to be swapped out (written onto disk) in order to provide free memory space for the requested page. The algorithm that decides which page to swap out is called the page replacement strategy. One of the widely-known replacement algorithm is called the least-recently-used (LRU) strategy.
The Problem:
In this problem, we’ll explore a variation of LRU known as the clock algorithm. This algorithm works as follows. Initially, all n page cells in memory are free; you can think of them as an array with indices.Each element of the array contains the amount of memory for one page, and a “flag”.The clock algorithm also keeps a “hand pointer”, which initially points to cell 1.
When the program needs to access a page, first it checks to see if the page is currently loaded in memory; if so, it simply accesses that page (no page fault) and sets the page’s flag to new.
If the page it needs is not currently loaded in memory, then it loads the page in the next available free cell (cell with the lowest index) if there is one available and sets the page’s flag to new. If there is no free cell, then it checks the cell pointed by hand pointer. If the page pointed by hand is marked as old, then it will be swapped out for the new request (i.e., the page is loaded and marked as new) and the pointer advances one position. If the page pointed by hand is marked as new(i.e., the page is not old), the algorithm then marks that cell/page as old and the pointer advances one position. Advancing the pointer simply means the pointer will point to the next memory cell (with 1 higher index), and wraps back to the first cell if advancing from the V8(FN@MLA2}ICS2DI0%NGOQ.png cell, similar to the hands of a clock. Eventually, some page pointed by the hand will be seen as old and is swapped out, giving a free cell for the requested page.
Note that when a page is referenced or loaded, its flag is set to new.
This strategy gives each cell a second chance, being set to old before getting swapped out. If a page is referenced while the cell/page is old,it will be marked as new again, indicating that it is recently used. Thus a page will only be swapped out if the hand pointer sees it twice (first time marks it as old,and second time swaps it out) without the page ever being used during that period.Your task is to implement the clock algorithm.
Input
There will be multiple test cases. The first line of each test case contains two integers, n(1≤n≤ 50),the number of page cells in available memory, and r (1 ≤ r≤ 50), the number of page requests made by the program. The next line contains r integers ri, (1 ≤ri≤50), separated by spaces. These are pages that are accessed by the program (the pages are listed in the order of being accessed by the program).
The last test case will be followed by a line which contains “0 0”, i.e., end-of-data is indicated by n = 0 and r = 0.
Output
At the beginning of each test case, output “Program p”,where p is the test case number (starting from 1). For each request, output: “Page ri loaded into cell c. ” if the request ri is not in memory, and is loaded into cell c. If the request ri is already in memory, output: “Access page ri in cell c” where c is the cell that page ri is located in memory. At the end of each test case, output: "There are a total of k page faults. "where k is the total number of page faults (loads) experienced during the execution of the program.
Leave a blank line after the output for each test case. Follow the format illustrated in Sample Output.
Sample Input
3 12
3 2 1 5 3 2 4 3 2 1 5 4
5 16
1 3 5 7 9 9 7 5 1 8 3 5 2 3 12 18
8 1
1
0 0
Sample Output
Program 1
Page 3 loaded into cell 1.
Page 2 loaded into cell 2.
Page 1 loaded into cell 3.
Page 5 loaded into cell 1.
Page 3 loaded into cell 2.
Page 2 loaded into cell 3.
Page 4 loaded into cell 1.
Access page 3 in cell 2.
Access page 2 in cell 3.
Page 1 loaded into cell 2.
Page 5 loaded into cell 3.
Access page 4 in cell 1.
There are a total of 9 page faults.
Program 2
Page 1 loaded into cell 1.
Page 3 loaded into cell 2.
Page 5 loaded into cell 3.
Page 7 loaded into cell 4.
Page 9 loaded into cell 5.
Access page 9 in cell 5.
Access page 7 in cell 4.
Access page 5 in cell 3.
Access page 1 in cell 1.
Page 8 loaded into cell 1.
Access page 3 in cell 2.
Access page 5 in cell 3.
Page 2 loaded into cell 4.
Access page 3 in cell 2.
Page 12 loaded into cell 5.
Page 18 loaded into cell 3.
There are a total of 9 page faults.
Program 3
Page 1 loaded into cell 1.
There are a total of 1 page faults.
理解
就是一道普通的大模拟
记录每一个,若已经被记录则输出位置,否则填入,若已满则覆盖
值得注意的是指针要随着题目的要求移动!
AC代码
#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
const int N = 1e2+5;
int main(){
int n,r;
int cas = 1;
while(~scanf("%d %d",&n,&r) && (n+r)){
printf("Program %d\n",cas++);
ll cnt = 0;
int a[60],b[60];
map<int,int> mp;
for(int i = 0;i <= n;i++) a[i] = 0,b[i] = 0;
int y = 1;
for(int i = 1;i <= r;i++){
int fl = 0;
int x;
scanf("%d",&x);
while(1){
if(mp[x]){
printf("Access page %d in cell %d.\n",x,mp[x]);
a[mp[x]] = 1;
fl = 1;
break;
}else if(a[y] == 0){
a[y] = 1;
b[y] = x;
printf("Page %d loaded into cell %d.\n",x,y);
cnt++;
mp[x] = y;
break;
}else if(a[y] == 1) a[y] = 2;
else if(a[y] == 2){
mp[b[y]] = 0;
b[y] = x;
mp[b[y]] = y;
a[y] = 1;
printf("Page %d loaded into cell %d.\n",x,y);
cnt++;
break;
}
y++;
if(y > n) y = 1;
}
if(fl) continue;
y++;
if(y > n) y = 1;
}
printf("There are a total of %lld page faults.\n\n",cnt);
}
return 0;
}
C -
题目描述
Rigid Reptile is trying to covertly infiltrate the compound of his nemesis Pistol Wildcat. The compound is under heavy surveillance by large numbers of video cameras and genetically enhanced soldiers. Luckily for Reptile, the soldiers’ enhancements grant them eyesight, hearing, and intelligence that is far inferior to that of an ordinary person. Between his cardboard box and tricks he picked up from Decoy Calamari, he’ll have little trouble evading the soldiers. The security cameras, though, are a different story.
The Problem:
The cameras in Pistol Wildcat’s compound have a circular detection radius which varies from camera to camera. Any unauthorized person (such as Rigid Reptile) who gets closer (≤) to a camera than the specified radius will immediately trigger an alarm. Ordinarily, the genetically enhanced soldiers think nothing of a person-sized cardboard box walking around, but when an alarm goes off, they are apt to shoot anything and everything. Naturally, Reptile would like to avoid this. You must write a program that, given Rigid Reptile’s path as a series of two-dimensional line segments and the positions and detection radii of the cameras, outputs which cameras (if any) Reptile gets too close to.
Input
Input begins with a single positive integer n, on a line by itself, indicating the number of compounds facing Rigid Reptile (i.e., the number of data sets to be processed). Following that line are n compound descriptions. The description of a compound begins with a line containing two integers c and p representing the number of cameras and the number of points along Reptile’s path, respectively, where 1 ≤c ≤ 50and 2 ≤p ≤ 50. The next c lines contain three integers indicating the x coordinate, y coordinate, and detection radius,respectively, of a camera (consider the first camera to be numbered 1, the second camera to be numbered 2, etc.). The following p lines each contain two integers representing the x and y coordinates of successive points along Reptile’s path (assume all points are distinct).
Output
Rigid Reptile moves in a straight line between successive points on his path. If at any time his Euclidean distance to a camera is less than orequal to its detection radius (or within 0.01), he has triggered that camera’s alarm. For each compound (data set), print a line indicating which cameras Reptile has triggered. This line should be of the form:
Compound #i: message
where i is the compound number (starting at 1). If Reptile triggered no cameras, message should be “Rigid Reptile was undetected”.If Reptile triggered one or more cameras, message should be of the form “Reptile triggered these cameras : list” where list is a list of the cameras triggered by reptile, sorted in ascending numerical order (leave exactly one space between numbers on this list).
Leave a blank line after the output for each data set. Follow the format illustrated in Sample Output.
Sample Input
3
3 3
5 5 3
2 8 2
7 3 1
4 5
2 7
6 3
1 4
0 0 5
10 0
10 10
0 10
0 20
2 2
0 0 5
20 0 5
13 1
27 1
Sample Output
Compound #1: Reptile triggered these cameras: 1 2 3
Compound #2: Rigid Reptile was undetected
Compound #3: Reptile triggered these cameras: 2
理解
就是一道数学题
给你几个圆心坐标半径为扫描范围
给定行走轨迹点,判断直线到圆心的距离
若d < r 则进入扫描范围记录 即可
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e3 + 7;
const int mod = 1e9 + 7;
const double PI = atan(1.0)*4;
const double ESP=1e-8;
vector<pair<double,double> > V,Y;
typedef pair<double,double> PAIR;
double r[maxn];
bool vis[maxn];
vector <int> ans;
bool judge(PAIR P,PAIR yuan,double R)// 判断是否在圆内
{
if( (P.first-yuan.first)*(P.first-yuan.first) + (P.second-yuan.second)*(P.second-yuan.second) -R*R <=0)
return 1;
return 0;
}
bool Judis(PAIR P1,PAIR P2,PAIR yuan,double R){
if(judge(P1,yuan,R)&&judge(P2,yuan,R))//都在圆内 不相交
return true;
if(!judge(P1,yuan,R)&&judge(P2,yuan,R)||judge(P1,yuan,R)&&!judge(P2,yuan,R))//一个圆内一个圆外 相交
return true;
double A,B,C,dist1,dist2,angle1,angle2;//Ax+By+C=0;//(y1-y2)x +(x2-x1)y +x1y2-y1x2=0
if(P1.first==P2.first)
A=1,B=0,C= -P1.first;
else if(P1.second==P2.second)
A=0,B=1,C= -P1.second;
else
{
A = P1.second-P2.second;
B = P2.first-P1.first;
C = P1.first*P2.second - P1.second*P2.first;
}
dist1 = A * yuan.first + B * yuan.second + C;
dist1 *= dist1;
dist2 = (A * A + B * B) * R * R;
if (dist1 > dist2) return false;//点到直线距离大于半径r 不相交
angle1 = (yuan.first - P1.first) * (P2.first - P1.first) + (yuan.second - P1.second) * (P2.second - P1.second);
angle2 = (yuan.first - P2.first) * (P1.first - P2.first) + (yuan.second - P2.second) * (P1.second - P2.second);
if (angle1 > 0 && angle2 > 0) return true;//余弦都为正,则是锐角 相交
return false;//不相交
}
int main(){
int cas;
scanf("%d",&cas);
for(int e = 1;e <= cas;e++){
int n,m;
scanf("%d %d",&n,&m);
V.clear();
Y.clear();
ans.clear();
double x,y;
for(int i = 1;i <= n;i++){
vis[i] = 0;
scanf("%lf %lf %lf",&x,&y,&r[i]);
Y.push_back(make_pair(x,y));
}
for(int i = 1;i <= m;++i){
scanf("%lf %lf",&x,&y);
V.push_back(make_pair(x,y));
}
for(int i = 1;i < V.size();++i){
for(int j = 0;j < Y.size();++j){
if(vis[j+1]) continue;
if(Judis(V[i-1],V[i],Y[j],r[j+1])){
vis[j+1] = 1;
ans.push_back(j+1);
}
}
}
printf("Compound #%d: ",e);
if(ans.size()){
sort(ans.begin(),ans.end());
printf("Reptile triggered these cameras:");
for(int i = 0;i < ans.size();++i) printf(" %d",ans[i]);
printf("\n\n");
}
else printf("Rigid Reptile was undetected\n\n");
}
return 0;
}
D - Lifeform Detector
题目描述
Government scientists at Area 51 are developing a new program to detect alien lifeforms. In particular, they are interested in finding evidence of additional visits by aliens in the 1950’s. From their first visit, the scientists have the make-up of the aliens’ DNA (which is radically different from human DNA). The complete grammar for the DNA is as follows (lower-case letters represent terminal symbols and is the empty string):
TheProblem:
Given possible alien DNA patterns, determine if they match the alien DNA description given by the grammar.
Input
The first line of the input will consist of a positive integer n,representing the number of DNA patterns (i.e., the number of data sets to be processed). Each of the next n lines will contain a string of lower-case letters (at least one letter and at most 50 letters) that represent the pattern to check against the alien DNA grammar. Note that the input will be at least one letter even though the grammar allows for empty (null) string, i.e., empty string will not be in the input. Assume that input will not contain any character other than lower-case letters.
Output
For each DNA pattern, output the header ''Pattern i: " where i is the number of the pattern in the input(starting with 1). Then, print “More aliens!” if the pattern matches the alien DNA description or "Still Looking."if the pattern does not match.
Leave a blank line after the output for each data set. Follow the format illustrated in Sample Output.
Sample Input
2
aacbcbcc
aa
Sample Output
Pattern 1: More aliens!
Pattern 2: Still Looking.
理解
这题目读题杀人
这得是企业级理解才能看出来只用判ab的个数
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
const double PI = atan(1.0)*4;
int main(){
int cas;
scanf("%d",&cas);
for(int e = 1;e <= cas;e++){
string s;
cin >> s;
int fl = 0;
int cnt1 = 0,cnt2 = 0;
for(int i = 0;i < s.size();i++){
if(s[i]<'a'||s[i] >'c') fl = 1;
if(s[i] == 'a') cnt1++;
if(s[i] == 'b') cnt2++;
}
if(cnt1 != cnt2) fl = 1;
printf("Pattern %d: ",e);
if(fl){
printf("Still Looking.\n\n");
}else{
printf("More aliens!\n\n");
}
}
return 0;
}
(二)2019-ICPC沈阳重现
A - Triangulation
题目描述
Rose is no longer satisfied by math, so she lets Jack start to learn geometry.
Today they work on such a problem: Given a simple polygon of n vertices on a plane, how many different triangulations of this polygon are there? The answer needs to module 998244353.
Simple polygon : A polygon that does not intersect itself and has no holes.
Triangulation : An edge set contains n−3 diagonal lines, and these lines only intersect at polygon vertices. These lines separate a simple polygon into n−2 triangles.
Input
The first line contains one integer n (3≤n≤200) — the number of vertices.
The next n lines contain the coordinates of the polygon vertices, where the i-th line contains two integers xi, yi (∣xi∣,∣yi∣ ≤ 1e6 ) — the coordinates of the polygon’s i-th vertex. The vertices are given clockwise or counterclockwise.
It is guaranteed that no three vertices are collinear.
Output
Output one integer in one line — the number of different triangulations module 998244353.
Sample Input
6
0 10
2 6
5 3
4 1
10 0
0 0
Sample Output
3
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 205;
const ll M = 998244353;
ll dp[N][N];
struct P{
ll x,y;
P(){}
P(ll x,ll y):x(x),y(y){}
} p[N];
ll cal(P a,P b){
return a.x*b.y-a.y*b.x;
}
inline P Pc(P a,P b){
return P(a.x-b.x,a.y-b.y);
}
void re(ll n){
ll i = 0,j = n-1;
while(i < j){
P t = p[i];
p[i] = p[j];
p[j] = t;
i++;
j--;
}
return ;
}
int main() {
ll n,sum = 0;
scanf("%lld",&n);
for(ll i = 0;i < n;++i) scanf("%lld%lld",&p[i].x,&p[i].y);
for(ll i = 1;i < n-1;++i) sum += cal(Pc(p[i],p[0]),Pc(p[i+1],p[0]));
if (sum < 0) re(n);
for(ll i = 0;i < n;++i) dp[i][(i+1)%n] = 1;
for(ll l = 2;l <= n;++l){
for(ll i = 0;i < n;++i){
ll j = (i+l)%n;
for(ll k = (i+1)%n;k != j;(++k) %= n)
if (cal(Pc(p[k],p[i]),Pc(p[j],p[i])) > 0) (dp[i][j]+=dp[i][k]*dp[k][j]) %= M;
}
}
printf("%lld\n",dp[0][n - 1]);
return 0;
}
(三)CF
A - Count the Arrays
题目描述
Your task is to calculate the number of arrays such that:
each array contains n elements;
each element is an integer from 1 to m;
for each array, there is exactly one pair of equal elements;
for each array a, there exists an index i such that the array is strictly ascending before the i-th element and strictly descending after it (formally, it means that aj<aj+1, if j<i, and aj>aj+1, if j≥i).
Input
The first line contains two integers n and m (2≤n≤m≤2⋅105).
Output
Print one integer — the number of arrays that meet all of the aforementioned conditions, taken modulo 998244353.
Sample Input
样例1:
3 4
样例2:
3 5
样例3:
42 1337
样例4:
100000 200000
Sample Output
样例1:
6
样例2:
10
样例3:
806066790
样例4:
707899035
理解
有一说一我推了一年也没找到规律
然后赛后看大佬推得
c(m,n-1)*2^(n-3)*(n-2)
c(m,n-1)是从m个数里选n-1个的组合
n-2是指n-1个数里重复的数字的选择
然后剩下的
n-3放左边 0个放右边
n-4放左边 1个放右边
n-5放左边 2个放右边
以此类推
然后根据下图公式化为
2^(n-3)
AC代码
写了还没交。。就不贸然放了,进不去主页的卑微网速
卑微.jpg
(四)我的感想
我杠我自己
ummm这周老是遇到题目卡我,每每换完方法A了就觉得之前的能改,然后就优化A之前的方法,总是不够细心的原因,并且了解到了sting前加的效率很低(我以前一直不晓得ummm)周三比赛堆一起了打怎么说呢,也没有觉得很累,就觉得自己能力不太够吧,写不出来提早下班,不过人的脑子只要在转,就是好的。