添加链接描述
直接判断墙的长和宽是否均长于 2 倍的 d,因为两边均要留有空隙窗户的最大面积为
(w-2d)(h-2*d)
#include
using namespace std;
int w,h,d;
int main(){
cin>>w>>h>>d;
if(w>2*d&&h>2*d)
printf("%d\n",(w-2*d)*(h-2*d));
else puts("0");
return 0;
}
添加链接描述
给定一个整数 n,后面紧接着 n 个字符串,代表着名字。
要求:字符串首字母相等,而两字符串不相等则为一种成功组合。问最多有多少组合。
其中 abc/acc 是一种成功组合,acc/abc 也是一种成功组合。
先排序是必须的,然后遍历一遍即可。
在相同的首字母中遍历,如果下一个与上一个不相同,则 ans+遍历的长度
若相同则 ans+上一次遍历的长度
#include
#include
#include
#include
using namespace std;
typedef long long ll;
bool cmp(string x,string y){
return x<y;
}
string str[100010];
int main(){
ll n,ans=0;
cin>>n;
for (int i=1;i<=n;i++) cin>>str[i];
sort(str+1,str+n+1,cmp);
int l=1,r=1;
char tmp=str[1][0];
for (int i=2;i<=n;i++){
if (str[i][0]!=tmp){
tmp=str[i][0];
l=r=1;
continue;
}
if (str[i]!=str[i-1]){
r=0;
}
ans+=2*(l-r);
l++; r++;
}
cout<<ans<<endl;
return 0;
}
添加链接描述
正难则反,我们可以先求出最多有多少个数字不需要移动就可以完成排序,至于怎么求,我
们可以发现那些严格递增子序列可以就不要移动,就比如样例:8, 3, 6, 7, 4, 1, 5, 2 。其中
3,4,5 可以不需要移动,所以我们需要找到最长严格递增的子序列。首先第一状态 dp【i】,
为以 i 结尾的严格递增的子序列,那么 dp【i】=dp【i-1】+1。找到最大的 dp 值,最后序列
长度 n-dp【i】就是答案了。
#include
using namespace std;
const int maxn=1e5+5;
int dp[maxn];
int a[maxn];
int main(){
int n,m;
int ans=0;
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
scanf("%d",&m);
dp[m]=dp[m-1]+1;
ans=max(dp[m],ans);
}
printf("%d\n",n-ans);
return 0;
}
添加链接描述
本题的关键是 XY=10^Z,XW=N,由于第一个式子的,我们可以得到 X 一定是 2,5 的乘积,所以我们先对 N 质数分解,记录 2,5 的个数,最后只要把这些 2,5 组合一下就可以了。
#include
using namespace std;
typedef long long ll;
vector<ll> vec;
ll qpow(ll n,ll m){
ll ans=1;
while(m){
if(m&1)ans=ans*n;
n=n*n;
m/=2;
}
return ans;
}
int main(){
ll n;
scanf("%lld",&n);
ll num1,num2;
num2=num1=0;
while(n%2==0&&n!=0){
n/=2;
num1++;
// cout<
}
while(n%5==0&&n!=0){
n/=5;
num2++;
// cout<
}
// cout<
for(int i=0;i<=num1;i++){
ll tem1=qpow(2,i);
for(int j=0;j<=num2;j++){
//tem1=tem1*qpow(5,j);
vec.push_back(tem1*qpow(5,j));
}
}
sort(vec.begin(),vec.end());
int ans1=vec.size();
printf("%d\n",ans1);
for(int i=0;i<ans1;i++){
printf("%lld\n",vec[i]);
}
return 0;
}
添加链接描述
本题是一道模拟题。我们可以定义数组 ans【i】记录员工已经得到的工资,base 数组记录
multiplier,最后定义 n 个 vertor,用来存某个员工的下属,当进行操作 1 时直接把下属的编
号放进相应的 vector,进行操作二时更新 base 数组,进行操作三时,更新当前员工及其下
属的 ans,更新的话写一个 dfs 就行了,当进行操作四是直接输出相应的 ans 就好了。
#include
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
ll base[maxn];
ll ans[maxn];
vector<int> vec[maxn];
void dfs(int now,ll val){
int len=vec[now].size();
ans[now]+=base[now]*val;
for(int i=0;i<len;i++){
//ans[vec[now][i]]+=base[vec[now][i]]*val;
dfs(vec[now][i],val);
}
}
int main(){
int n;
ll s;
int num;
num=1;
scanf("%d%lld",&n,&s);
for(int i=0;i<maxn;i++)base[i]=s;
memset(ans,0,sizeof(ans));
while(n--){
ll val;
int id,op;
scanf("%d",&op);
if(op==1){
scanf("%d",&id);
num++;
vec[id].push_back(num);
}
else if(op==2){
scanf("%d%lld",&id,&val);
base[id]=val;
}
else if(op==3){
scanf("%d%lld",&id,&val);
dfs(id,val);
}
else{
scanf("%d",&id);
printf("%lld\n",ans[id]);
}
}
return 0;
}
添加链接描述
给定一个整数 m,长度小于 10。再给出一个整数 n,后面紧接着 n 个整数,同时允
许一个数 x,x 可以选 1 到 99 的数字,总共 n+1 个整数。
问是否存在将 n+1 个整数随意选出某些数,可以拼凑成 m,这里 033 与 33 不相等,即拼凑
成的数要完全等于 m。若能输出 1,不能则输出 0。
m 的长度小,直接搜索。
记得处理几种特殊情况,首字符为 0 的时候,必不能实现拼凑。然后有种特殊情况是可
以任意选择一个数(1 到 99),为了处理这种情况可以每次搜索都走两次,一次是取 1~9 的,
另外一次是取 10~99,详情看代码。
#include
#include
using namespace std;
typedef long long ll;
ll str;
ll n,len,a[20],b[30],c[30];
void init(){
scanf("%lld%lld",&str,&n);
ll tmp=str;
len=0;
while (tmp){
len++;
tmp/=10;
}
for (ll i=len-1;i>=0;i--){
a[i]=str%10;
str/=10;
}
for (ll i=0;i<n;i++){
scanf("%lld",&tmp);
b[i]=tmp/10;
c[i]=tmp%10;
}
}
ll bfs(ll pos,ll flag,ll vis[]){
if (pos==len) return 1;
if (pos>len||a[pos]==0) return 0;
if (flag==0&&(bfs(pos+1,1,vis)||bfs(pos+2,1,vis))) return 1; //处理任选情况
for (ll j=0;j<n;j++){
if(!vis[j]){
ll t=0;
for (ll k=0;k<j;k++){ //剪枝
if (!vis[k]&&c[j]==c[k]&&b[j]==b[k]){
t=1;
break;
}
}
if (t) continue;
if (b[j]==0){
if (c[j]==a[pos]){
vis[j]=1;
if (bfs(pos+1,flag,vis)) return 1;
vis[j]=0;
}
}
else if(pos+1<len){
if (b[j]==a[pos]&&c[j]==a[pos+1]){
vis[j]=1;
if (bfs(pos+2,flag,vis)) return 1;
vis[j]=0;
}
}
}
}
return 0;
}
int main(){
init();
ll vis[30];
memset(vis,0,sizeof(vis));
printf("%lld\n",bfs(0,0,vis));
return 0;
}
添加链接描述
直接模拟判断字符串中每个字符出现的次数
如果均是偶数次输出 0
如果均是奇数次输出 1
如果均有则输出 2
#include
using namespace std;
char s[75];
int cnt[30];
int main() {
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;i++)
cnt[s[i]-'a']++;
int flageven=0,flagodd=0;
for(int i=0;i<26;i++){
if(cnt[i]>0&&cnt[i]%2==0)flageven=1;
if(cnt[i]%2==1) flagodd=1;
}
if (flageven&&flagodd) printf("2\n");
else if(flageven) printf("0\n");
else printf("1\n");
return 0;
}
添加链接描述
简单贪心
楼层的范围是 1 到 999,直接判断每个楼层是否可达,
假如该楼层中包含损坏的数字则不可达,否则可达,注意特判 0 层的情况
若该楼层可达且比当前答案值更小,则更新答案
#include
using namespace std;
int n,broken[10],target;
bool check(int x){
if(x==0&&broken[0]) return false;
while(x){
int pos=x%10;
if(broken[pos]) return false;
x/=10;
}
return true;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
broken[x]=1;
}
cin>>target;
int ans=1000;
for(int i=0;i<=999;i++){
if(check(i))
ans=min(ans,abs(i-target));
}
cout<<ans<<endl;
return 0;
}
添加链接描述
给出 w,h 和 x,礼物盒的规格是(wh),x 是巧克力的总面积值。
要求做出最多的巧克力数目。其中做出的巧克力可以放入礼物盒
,并且每种巧克力规格都不同(规格 ab 与规格 ba 视作不一样),若盒子
规格是 ab(a!=b),那么能放下 ab 的巧克力,而不能放下 ba 的巧克力。
比较出 w,h 的最小值,设 w 更小。判定盒子能否装入 w*w 规格的巧克力。
#include
#include
typedef struct Pair {
long long area;
long long count;
} Pair;
long long getMin(long long a, long long b) {
return a < b ? a : b;
}
// Returns the sum of all integers in the range [a, b]
long long sumRange(long long a, long long b) {
if (b < a) {
return 0;
}
long long len = b - a + 1;
return (a - 1) * len + len * (len + 1) / 2;
}
// Returns the sum (as a double) of all integers in the range [a, b]
double sumRangeDouble(double a, double b) {
if (b < a) {
return 0;
}
double len = b - a + 1;
return (a - 1) * len + len * (len + 1) / 2;
}
// Returns a pair of total area and number of unique bars that can bemade
// with each bar having area at most maxSize and fitting into a boxof size w x h
Pair calc(long long w, long long h, long long maxSize) {
Pair p;
double dArea = 0.0;
double dCount = 0.0;
long long MAX_X = 1000000;
// Do everything with doubles first to skip cases that overflow
for (long long x = 1; x <= w && x <= MAX_X; x++) {
if (maxSize / x == 0) break;
if (x * x > maxSize) break;
// x < y
{
long long minY = x + 1;
long long maxY = getMin(h, maxSize / x);
if (minY <= maxY) {
dCount += maxY - minY + 1;
dArea += x * sumRangeDouble(minY, maxY);
}
}
// y <= x
{
long long minY = x;
long long maxY = getMin(w, maxSize / x);
if (minY <= maxY) {
dCount += maxY - minY + 1;
dArea += x * sumRangeDouble(minY, maxY);
}
}
}
if (dArea >= 1.1e18) {
p.area = 1100000000000000000LL;
p.count = 0;
return p;
}
p.area = 0;
p.count = 0;
for (long long x = 1; x <= w && x <= MAX_X; x++) {
if (maxSize / x == 0) break;
if (x * x > maxSize) break;
// x < y
{
long minY = x + 1;
long maxY = getMin(h, maxSize / x);
if (minY <= maxY) {
p.count += maxY - minY + 1;
p.area += x * sumRange(minY, maxY);
}
}
// y <= x
{
long minY = x;
long maxY = getMin(w, maxSize / x);
if (minY <= maxY) {
p.count += maxY - minY + 1;
p.area += x * sumRange(minY, maxY);
}
}
}
return p;
}
int main(void) {
long long w, h, x;
scanf("%lld %lld %lld", &w, &h, &x);
if (w > h) {
long long tmp = w;
w = h;
h = tmp;
}
long long min = 1;
long long max = 2000000000LL;
while (min < max) {
long long mid = (min + max + 1) / 2;
Pair p = calc(w, h, mid);
if (p.area > x) {
max = mid - 1;
}
else {
min = mid;
}
}
Pair p = calc(w, h, min);
Pair p2 = calc(w, h, min + 1);
long long possibleExtra = p2.count - p.count;
long long ans = p.count + getMin(possibleExtra, (x - p.area) /
(min + 1));
printf("%lld\n", ans);
return 0;
}
添加链接描述
判断正方形与圆是否相交
(1)正方形与圆有面积交,有两种情况
a、正方形的某个顶点在圆内
b、圆的上下左右点或圆心即(x,y+r)(x,y-r)(x-r,y)(x+r,y)(x,y)五个点的任意点在正方形内 (注意一定要判断圆心,有可能正方形的四个顶点都在圆上,此时也有面积交)
(2)正方形与圆有接触在一个点,有两种情况
a、正方形的某个顶点在圆上
b、圆的上下左右点即(x,y+r)(x,y-r)(x-r,y)(x+r,y)四个点的任意一个点在正方形上
(3)如果不是以上两种情况,则为相离
#include
using namespace std;
int x,y,r,tx,ty,s;
int dotInCircle(int a,int b){
if((x-a)*(x-a)+(y-b)*(y-b)<r*r) return 1;
else if ((x-a)*(x-a)+(y-b)*(y-b)==r*r) return 2;
else return 0;
}
int dotInSquare(int a,int b){
if(a>tx&&a<tx+s&&b>ty&&b<ty+s) return 1;
else if(a==tx&&b>=ty&&b<=ty+s
||a==tx+s&&b>=ty&&b<=ty+s
||a>=tx&&a<=tx+s&&b==ty
||a>=tx&&a<=tx+s&&b==ty+s) return 2;
else return 0;
}
bool overlap(){
return dotInCircle(tx,ty)==1
||dotInCircle(tx+s,ty)==1
||dotInCircle(tx,ty+s)==1
||dotInCircle(tx+s,ty+s)==1
||dotInSquare(x,y)==1
||dotInSquare(x+r,y)==1
||dotInSquare(x-r,y)==1
||dotInSquare(x,y+r)==1
||dotInSquare(x,y-r)==1;
}
bool touch(){
return dotInCircle(tx,ty)==2
||dotInCircle(tx+s,ty)==2
||dotInCircle(tx,ty+s)==2
||dotInCircle(tx+s,ty+s)==2
||dotInSquare(x+r,y)==2
||dotInSquare(x-r,y)==2
||dotInSquare(x,y+r)==2
||dotInSquare(x,y-r)==2;
}
int main(){
cin>>x>>y>>r;
cin>>tx>>ty>>s;
if(overlap()) puts("2");
else if(touch()) puts("1");
else puts("0");
return 0;
}
添加链接描述
最短路问题
首先预处理出 team1 的任意两个队员是否相距为 1(相距为 1 的条件为 team1 或 team2 中
除该两个队员之外的任意一个队员均不在该两个队员形成的线段上),如果相距为 1 将他们
的的距离设置为 1,否则将他们的距离设置为无穷大然后采用 Floyd 求出 1 到 n 的最短路径即
为答案
#include
using namespace std;
const int INF=0x3f3f3f3f;
int n;
struct node{
int x,y;
}team1[15],team2[15];
int dis[15][15];
bool between(node a,node b,node c){
if(c.x>=min(a.x,b.x)&&c.x<=max(a.x,b.x)
&&c.y>=min(a.y,b.y)&&c.y<=max(a.y,b.y)
&&(c.y-a.y)*(b.x-a.x)==(b.y-a.y)*(c.x-a.x))
return true;
return false;
}
bool check(int a,int b){
for(int i=1;i<=n;i++)
if(a!=i&&b!=i&&between(team1[a],team1[b],team1[i])) return false;
for(int i=1;i<=n;i++)
if(between(team1[a],team1[b],team2[i])) return false;
return true;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>team1[i].x>>team1[i].y;
for(int i=1;i<=n;i++)cin>>team2[i].x>>team2[i].y;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) dis[i][j]=0;
else if(check(i,j)) dis[i][j]=1;
else dis[i][j]=INF;
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
if(dis[1][n]==INF) puts("-1");
else cout<<dis[1][n]<<endl;
return 0;
}
添加链接描述
思路见代码
#include
#include
#define EPS 1e-6
#define RADIUS 6371
#define PI 3.14159265358979
typedef struct Vec {
double x, y, z;
} Vec;
double min(double a, double b) {
return a < b ? a : b;
}
Vec newVec(double x, double y, double z) {
Vec v;
v.x = x;
v.y = y;
v.z = z;
return v;
}
Vec vecAdd(Vec a, Vec b) {
return newVec(a.x + b.x, a.y + b.y, a.z + b.z);
}
Vec vecSub(Vec a, Vec b) {
return newVec(a.x - b.x, a.y - b.y, a.z - b.z);
}
double vecDot(Vec a, Vec b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
double vecMag2(Vec v) {
return vecDot(v, v);
}
double vecMag(Vec v) {
return sqrt(vecMag2(v));
}
Vec vecScale(Vec v, double s) {
return newVec(v.x * s, v.y * s, v.z * s);
}
Vec vecScaleTo(Vec v, double s) {
return vecScale(v, s / vecMag(v));
}
Vec vecNormalize(Vec v) {
return vecScaleTo(v, 1);
}
Vec vecCross(Vec a, Vec b) {
return newVec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x *
b.y - a.y * b.x);
}
// Given a plane defined by a, b, and c, returns the projection of ponto the plane.
Vec vecProj(Vec a, Vec b, Vec c, Vec p) {
Vec ab = vecSub(b, a);
Vec ac = vecSub(c, a);
Vec norm = vecNormalize(vecCross(ab, ac));
return vecSub(p, vecScale(norm, vecDot(vecSub(p, a), norm)));
}
int sig(double x) {
if (fabs(x) < EPS)
return 0;
return x < 0 ? -1 : 1;
}
// Given the latitude and longitude (in degrees), returns the 3dpoint
// on the sphere of radius 6371km centered around the origin.
Vec getPointOnEarth(double lat, double lon) {
lat = lat * PI / 180;
lon = lon * PI / 180;
double x = cos(lat) * cos(lon);
double y = cos(lat) * sin(lon);
double z = sin(lat);
return vecScale(newVec(x, y, z), RADIUS);
}
int main(void) {
int n;
// Read in number of trips.
scanf("%d", &n);
// Get the points for the northPole and the origin.
Vec northPole = getPointOnEarth(90, 0);
Vec origin = newVec(0, 0, 0);
for (int tripI = 0; tripI < n; tripI++) {
double lat0, lon0, lat1, lon1;
scanf("%lf", &lat0);
scanf("%lf", &lon0);
scanf("%lf", &lat1);
scanf("%lf", &lon1);
int onEquator = fabs(lat0) < 1e-9 && fabs(lat1) < 1e-9;
// Get the points of the two cities.
Vec p0 = getPointOnEarth(lat0, lon0);
Vec p1 = getPointOnEarth(lat1, lon1);
// Calculate the initial minimum distance.
double minDist = min(vecMag(vecSub(p0, northPole)),
vecMag(vecSub(p1, northPole)));
// Get a vector perpendicular to the plane defined by theorigin and the two cities.
Vec norm = vecCross(p0, p1);
// Project the north pole on to the plane defined by theorigin and the two cities.
Vec proj = vecProj(origin, p0, p1, northPole);
// Get the sign of the cross product (on the plane) from theprojected north pole to both cities.
int sig0 = sig(vecDot(vecCross(proj, p0), norm));
int sig1 = sig(vecDot(vecCross(proj, p1), norm));
// If the projected point is between the smallest arc formedby the two, Alex is right.
if (!onEquator && sig0 == -1 && sig1 == 1) {
double originalMinDist = minDist;
// Get the true minimum distance.
minDist = vecMag(vecSub(northPole, vecScaleTo(proj,RADIUS)));
printf("Alex\n");
}
else {
printf("Timothy\n");
}
// Print out the minimum distance.
printf("%.6f\n\n", minDist);
}
return 0;
}
觉得还行 的可以三连支持一波!(hhhhh…)